在Java中,我偶尔会直接抛出AssertionError
,断言不会到达某一特定行。这样做的一个示例是声明无法访问default
语句中的switch
个案(例如,请参阅this JavaSpecialists page)。
我想在.Net中使用类似的机制。我可以使用相同的例外吗?或者是否有另一种方法可以使用相同的效果?
编辑 - 为了澄清,我正在寻找一种机制来在发布的代码中标记运行时的失败,以指示代码中某些不变量(可能是灾难性的)失败。链接的示例生成0到2(包括0和2)之间的随机整数,并声明生成的数字始终为0,1或2.如果此断言不成立,则最好完全停止执行而不是继续使用某些未知数腐败的系统状态。
答案 0 :(得分:9)
我通常会根据值的来源抛出InvalidOperationException
或ArgumentOutOfRangeException
。
或者,有Debug.Assert
(只有在定义了DEBUG预处理程序符号时才会失败)或在.NET 4.0中,您可以使用Contract.Fail
,Contract.Assert
或{{1根据情况而定。显式抛出异常有一个好处,即编译器知道下一个语句是无法访问的。
我不是Contract.Assume
的忠实粉丝 - 它通常不适合发布(因为它会抛出一个断言框而不仅仅是失败),并且默认情况下它不会在发布中被触发。我更喜欢总是被抛出的异常,因为它们会阻止你的代码继续进行,无论是否有机会发现“东西是错误的”。
Code Contracts在某种程度上改变了游戏,因为在执行时有各种各样的选项可以保留,而静态检查器可以帮助证明你不会进入那种状态。您仍然需要选择执行时间策略...
答案 1 :(得分:1)
您可以使用Trace.Assert
方法,该方法适用于发布版本(如果您定义了TRACE
编译符号,默认情况下在Visual Studio项目中定义)。您还可以通过TraceListener
自定义应用程序对断言错误的反应方式。默认情况下(不出所料)DefaultTraceListener
,如果应用程序以交互模式运行,它将在对话框中显示断言。例如,如果要抛出异常,可以创建自己的TraceListener
并将其抛出方法Fail
。然后,您可以移除DefaultTraceListener
并使用您自己的programmatically或configuration file。
这看起来很麻烦,如果您想通过跟踪侦听器动态更改应用程序处理断言的方式,那么这是合理的。对于您总是想要失败的违规行为,请创建您自己的AssertionException
课程并立即将其丢弃。
对于.NET 4.0,我会定义一下Contract.Assert
方法。但是,只有在定义符号DEBUG
或CONTRACTS_FULL
时才会编译此方法。 DEBUG
无法在发布版本上运行,CONTRACTS_FULL
也会启用所有其他合同检查,其中一些可能不希望出现在发布版本中。