12

在 Java 中,我偶尔会AssertionError直接抛出一个,以断言不会到达特定的行。这方面的一个例子是断言语句中的defaultcaseswitch无法到达(请参阅此 JavaSpecialists 页面以获取示例)。

我想在.Net 中使用类似的机制。是否有我可以使用的等效异常?或者有没有其他方法可以达到同样的效果?

编辑- 澄清一下,我正在寻找一种机制来在运行时在已发布的代码中标记故障,以表明代码中的某些不变量发生了(可能是灾难性的)故障。链接示例生成一个介于 0 和 2(含)之间的随机整数,并断言生成的数字始终为 0、1 或 2。如果此断言不成立,最好完全停止执行,而不是继续执行一些未知数系统的损坏状态。

4

2 回答 2

11

我通常会抛出InvalidOperationExceptionArgumentOutOfRangeException取决于价值的来源。

或者,有Debug.Assert(仅当您定义了 DEBUG 预处理器符号时才会失败)或在 .NET 4.0 中您可以使用Contract.FailContract.AssertContract.Assume视情况而定。显式抛出异常的好处是编译器知道下一条语句是不可达的。

我不是很喜欢Debug.Assert- 它通常不适合发布(因为它会抛出一个断言框而不仅仅是失败)并且默认情况下它不会在发布时触发。我更喜欢总是抛出的异常,因为它们会阻止您的代码在有机会检测到“东西错误”之后继续执行。

代码契约在一定程度上改变了游戏规则,因为在执行时保留了各种选项,静态检查器可以帮助证明您不会进入那种状态。您仍然需要选择执行时间策略...

于 2009-08-10T10:08:25.027 回答
1

您可以使用该Trace.Assert方法,该方法适用于发布版本(如果您TRACE定义了编译符号,该符号在 Visual Studio 项目中默认定义)。您还可以通过TraceListener. 默认值为(不出所料) the DefaultTraceListener,如果应用程序在交互模式下运行,它将在对话框中显示断言。例如,如果你想抛出一个异常,你可以创建自己的TraceListener并在方法上抛出它Fail然后,您可以通过编程方式或在配置文件中删除DefaultTraceListener并使用您自己的。

这看起来很麻烦,只有当您想动态更改应用程序通过跟踪侦听器处理断言的方式时才合理。对于您总是希望失败的违规行为,请创建自己的AssertionException类并立即将其丢弃。

对于 .NET 4.0,我肯定会查看该Contract.Assert方法。但是,此方法仅在符号DEBUGCONTRACTS_FULL被定义时编译。DEBUG不适用于发布版本,并且CONTRACTS_FULL还将打开所有其他合同检查,其中一些您可能不希望出现在发布版本中。

于 2010-03-02T16:34:13.707 回答