将断言放入我们的代码的意义何在?自信编程有什么好处?自信编程的好处
private void WriteMessage(string message)
{
Debug.Assert(message != null, "message is null");
File.WriteAllText(FILE_PATH, message);
}
例如,我们可以检查消息变量并在此处引发异常。为什么我在这里使用断言?或者这是一个错误的例子来看到断言的好处?
将断言放入我们的代码的意义何在?自信编程有什么好处?自信编程的好处
private void WriteMessage(string message)
{
Debug.Assert(message != null, "message is null");
File.WriteAllText(FILE_PATH, message);
}
例如,我们可以检查消息变量并在此处引发异常。为什么我在这里使用断言?或者这是一个错误的例子来看到断言的好处?
他们也支持快速失败的哲学,Jim Shore在this article中解释过。
如果方法有一个指定的前置条件来取非空消息参数,那么只要前提条件不成立,程序就会立即失败,并且错误的来源必须被修复。
我认为断言在开发安全关键软件时更重要。当然,当软件被正式指定时,你更愿意使用断言。
对于断言(以及许多其他与代码构造相关的主题)的精彩讨论,请查看Steve McConnel的Code Complete。他花了整整一章来有效地使用断言。
我用它们来验证我已经提供了有效的依赖类。例如在构造函数DI中,您通常会接受某些您依赖的外部类来提供某些操作或服务。所以你可以断言(classRef! - null,“classRef不能为null”);而不是等你将消息传递给classRef并获取其他异常(如异常:访问冲突或类似含糊不清的内容,这些内容可能不会立即看到代码)。
要考虑的一个重要区别是你想用断言来捕捉哪种错误。我经常使用断言来捕捉编程错误(即,调用一个带有空参数的方法)和一个处理验证错误的不同机制(例如,传入错误长度的社会安全号码)。对于断言所带来的编程错误,我想快速失败。对于验证错误,我想要反应不那么剧烈,因为数据中可能存在错误(例如,用户正在进行某种数据输入)可能是正常的。在这些情况下,正确的处理可能是将错误报告给用户并继续运行。
哪里有人会写:
/*
* This can never happen
*/
它更实际的写:
assert(i != -1);
我喜欢使用断言,因为它们很容易用一个简单的编译时间关闭不变,或制成做一些其他事情,比如准备一份错误报告。我通常不会在发布某些内容时断言(至少,并非以通常的方式)。
使用它们使我不会在其他人的计算机上犯下非常愚蠢的错误......那些喜欢测试我的Alpha代码的勇敢的灵魂。使用它们加上像valgrind这样的工具有助于保证我在提交之前捕捉到一些可怕的东西。
测试我们的假设是非常有用的。断言不断确保不变量成立。总之它是用于以下目的,
有时,当我们不想使用try/catch/throw的时候,我喜欢使用assert_return()。
private void WriteMessage(string message)
{
assert_return(message != null, "message is null"); // return when false
File.WriteAllText(FILE_PATH, message);
}
我建议assert_return()通过报告测试版本中的错误来暂停应用程序。然后在生产系统中,它应该记录和错误,并从函数返回,说它不能这样做。
我之所以评论这一点是因为它遵循了“按合同设计”一书中的设计原则。您在哪里指定您的功能前后条件。虽然后置条件通常会根据上下文而趋向于更复杂的前提条件。 只是一个迷你的答案。断言对于捕捉开发人员或错过团队之间关于如何操作模块的通信非常有用。此外,引擎的核心框架和用户输入区域之间应该分开来混合两个是非常愚蠢的。 – Chad 2009-10-19 01:50:42