8

将断言放入我们的代码有什么意义?断言式编程有什么好处?

private void WriteMessage(string message)
{
    Debug.Assert(message != null, "message is null");

    File.WriteAllText(FILE_PATH, message);
}

例如,我们可以检查消息变量并在此处抛出异常。为什么我在这里使用断言?或者这是一个看到断言好处的错误例子?

4

7 回答 7

10

他们还支持快速失败的哲学,Jim Shore在这篇文章中对此进行了解释。

于 2009-04-24T21:37:29.477 回答
7

有些人会写:

/*
 * This can never happen
 */

写起来更实用:

assert(i != -1);

我喜欢使用断言,因为它们很容易通过一个简单的编译时间常数关闭,或者可以用来做其他事情,比如准备错误报告。在发布某些内容时,我通常不会打开断言(至少,不是以通常的方式)。

使用它们使我免于在其他人的计算机上犯非常愚蠢的错误.. 那些喜欢测试我的 alpha 代码的勇敢灵魂。使用它们加上 valgrind 之类的工具有助于确保我在提交之前发现了一些可怕的东西。

于 2009-04-25T01:01:47.473 回答
2

要考虑的一个重要区别是您希望使用断言捕获哪些类型的错误。我经常使用断言来捕获编程错误(例如,调用带有空参数的方法)和处理验证错误的不同机制(例如,传递错误长度的社会安全号码)。对于断言捕获的编程错误,我想快速失败。对于验证错误,我希望反应不那么激烈,因为数据中出现错误可能是正常的(例如,用户进行某种数据输入)。在这些情况下,正确的处理可能是将错误报告给用户并继续运行。

于 2009-04-25T00:27:24.887 回答
1

如果该方法有一个指定的前提条件来采用非空消息参数,那么您希望程序在前提条件不成立时立即失败,然后必须修复错误的根源。

我相信在开发安全关键型软件时,断言更为重要。当然,您更愿意在正式指定软件时使用断言。

于 2009-04-24T21:37:27.277 回答
1

有关断言(以及与代码构造相关的许多其他主题)的精彩讨论,请查看Steve McConnel 的Code Complete。他用一整章的时间来有效地使用断言。

于 2009-04-24T21:39:30.673 回答
1

我使用它们来验证是否为我提供了有效的依赖类。例如,在构造函数 DI 中,您通常接受某种外部类,您依赖这些类来提供某些操作或服务。

所以你可以断言(classRef !- null,"classRef 不能为 null"); 而不是等待您将消息传递给 classRef 并获得其他一些异常,例如异常:访问冲突或同样模棱两可的东西,可能不会立即从查看代码中明显看出。

于 2009-04-24T22:01:25.923 回答
0

测试我们的假设非常有用。断言不断确保不变量成立。简而言之,它用于以下目的,

  • 它允许实现快速故障系统。
  • 由于副作用,它减少了错误传播。
  • 它禁止(某种健全性检查)系统由于用户数据或后续代码更改而进入不一致状态。

有时,当我们不想使用 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() 通过在测试构建中报告错误来停止应用程序。然后在生产系统中,它应该记录和错误并从函数返回,说它不能这样做。

于 2017-01-03T17:24:43.380 回答