170

我正在使用断点进行调试,并且我实现了断言调用?我认为这仅用于单元测试。它除了断点还有什么作用?既然可以断点,为什么要使用 Assert?

4

9 回答 9

216

在调试编译Assert中,将布尔条件作为参数,如果条件为假,则显示错误对话框。如果条件为真,程序继续进行而不会中断。

如果你在 Release 中编译,所有Debug.Assert的 's 都会被自动排除在外。

于 2008-10-02T17:25:41.397 回答
104

代码完成

8 防御性编程

8.2 断言

断言是在开发过程中使用的代码——通常是例程或宏——允许程序在运行时检查自身。当断言为真时,这意味着一切都按预期运行。当它为假时,这意味着它在代码中检测到意外错误。例如,如果系统假设客户信息文件的记录永远不会超过 50,000 条,则程序可能包含记录数小于或等于 50,000 条的断言。只要记录数小于或等于 50,000,断言就会保持沉默。但是,如果它遇到超过 50,000 条记录,它会大声“断言”程序中存在错误。

断言在大型复杂程序和高可靠性程序中特别有用。它们使程序员能够更快地清除不匹配的接口假设、修改代码时出现的错误等等。

一个断言通常需要两个参数:一个布尔表达式,描述假设为真,如果不是,则显示消息。

(……)

通常,您不希望用户在生产代码中看到断言消息;断言主要用于开发和维护期间。断言通常在开发时编译到代码中,并从代码中编译出来用于生产。在开发过程中,断言会清除矛盾的假设、意外情况、传递给例程的错误值等等。在生产过程中,它们是从代码中编译出来的,因此断言不会降低系统性能。

于 2008-10-02T17:36:44.587 回答
40

当您不想为检查变量的每一行代码都设置断点时,您应该使用它,但如果存在某些情况,您确实希望获得某种反馈,例如:

Debug.Assert(someObject != null, "someObject is null! this could totally be a bug!");
于 2008-10-02T17:31:13.927 回答
16

Assert 还为您提供了另一个机会来嘲笑 Microsoft 的 UI 设计技能。我的意思是:一个包含三个按钮 Abort、Retry、Ignore 的对话框,以及如何在标题栏中解释它们的说明!

于 2008-10-02T17:33:02.973 回答
11

首先Assert()方法可用于TraceDebug类。
Debug.Assert()仅在调试模式下执行。
Trace.Assert()正在调试和发布模式下执行。

这是一个例子:

        int i = 1 + 3;
        // Debug.Assert method in Debug mode fails, since i == 4
        Debug.Assert(i == 3);
        Debug.WriteLine(i == 3, "i is equal to 3");

        // Trace.Assert method in Release mode is not failing.
        Trace.Assert(i == 4);
        Trace.WriteLine(i == 4, "i is equla to 4");

        Console.WriteLine("Press a key to continue...");
        Console.ReadLine();

在调试模式下运行此代码,然后在发布模式下运行。

在此处输入图像描述

您会注意到,在调试模式期间,您的代码Debug.Assert语句失败,您会看到一个消息框,显示应用程序的当前堆栈跟踪。这不会在 Release 模式下发生,因为Trace.Assert()condition 为 true (i == 4)

WriteLine()方法只是为您提供了将信息记录到 Visual Studio 输出的选项。 在此处输入图像描述

于 2017-01-02T19:12:25.837 回答
10

Assert 允许您断言在您的代码中应用的条件(post 或 pre)。这是一种记录您的意图并让调试器在未满足您的意图时通过对话框通知您的方式。

与断点不同,Assert 与您的代码一起使用,可用于添加有关您的意图的其他详细信息。

于 2008-10-02T17:26:03.020 回答
10

Assert 可以帮助您在测试和发布之间提供单独的消息传递行为。例如,

Debug.Assert(x > 2)

如果您正在运行“调试”构建,而不是发布构建,则只会触发中断。这里有一个关于这种行为的完整例子

于 2008-10-02T17:27:53.983 回答
5

断言在按合同设计 (DbC) 中占有重要地位,据我所知,这是由 Meyer, Bertand 介绍/认可的。1997. 面向对象的软件构造。

一个重要的特性是它们不能产生副作用,例如,您可以使用 if 语句(防御性编程)处理异常或采取不同的行动。

断言用于检查合同的前/后条件、客户/供应商关系 - 客户必须确保满足供应商的先决条件,例如。发送 5 英镑,供应商必须确保满足后置条件,例如。送出12朵玫瑰。(只是对客户/供应商的简单解释——可以接受更少,交付更多,但关于断言)。C# 还引入了 Trace.Assert(),可用于发布代码。

要回答这个问题,是的,它们仍然有用,但可以增加代码的复杂性+可读性和时间+难以维护。我们还应该使用它们吗?是的,我们都会使用它们吗?可能不是,或者不是迈耶描述的程度。

(即使是我学习此技术的 OU Java 课程也只显示了简单的示例,其余代码并未对大多数代码强制执行 DbC 断言规则,而是假定用于确保程序的正确性!)

于 2010-11-16T21:03:42.590 回答
3

我认为它的方式是 Debug.Assert 是一种建立关于如何调用方法的协定的方法,重点关注关于参数值的细节(而不仅仅是类型)。例如,如果您不应该在第二个参数中发送空值,则在该参数周围添加 Assert 以告诉使用者不要这样做。

它可以防止某人以愚蠢的方式使用您的代码。但它也允许这种愚蠢的方式进入生产环境,而不是向客户传达令人讨厌的信息(假设您构建了发布版本)。

于 2008-10-02T17:51:41.867 回答