2009-08-10 87 views
8

在Java中,我偶尔会直接抛出一个AssertionError来断言无法达到某一行。这方面的一个例子是断言无法到达switch声明中的default个案(例如,参见this JavaSpecialists page)。.Net相当于Java的AssertionError

我想在.Net中使用类似的机制。是否有可以使用的等价异常?还是有另一种方法可以用于相同的效果?为了说明问题,我正在寻找一种机制,在运行时在发布的代码中标记失败,以指示代码中的某个不变量(可能是灾难性的)失败。链接的例子生成一个介于0和2之间的随机整数(包括0和2),并声明生成的数字总是0,1或2.如果这个断言不成立,最好是完全停止执行,而不是继续执行一些未知的系统的腐败状态。

回答

8

根据价值的来源,我通常会抛出InvalidOperationExceptionArgumentOutOfRangeException

另外,还有Debug.Assert(当你有定义的DEBUG预处理符号这只会失败),或在.NET 4.0中,你可以使用Contract.FailContract.AssertContract.Assume视情况而定。显式抛出异常有一个好处,即编译器知道下一个语句不可访问。

我不是Debug.Assert的粉丝 - 它通常不适合发布(因为它抛出了断言框而不是失败),默认情况下它不会在发布中触发。我更喜欢总是抛出的异常,因为它们会阻止您的代码继续执行,无论是在发现“原因错误”的机会之后。

代码合同有点改变了游戏,因为在执行时有各种各样的选项可供选择,而静态检查程序可以帮助证明您不会进入该状态。您仍然需要选择,虽然执行时间的政策......

1

可以使用Trace.Assert方法,这将在发行工作中产生(如果您已经定义了TRACE编译符号,它在默认情况下Visual Studio项目定义) 。您还可以通过TraceListener自定义应用程序对断言错误的反应方式。默认情况下(不出意外)DefaultTraceListener,如果应用程序在交互模式下运行,它将在对话框中显示断言。例如,如果您想抛出异常,则可以创建自己的TraceListener并将其投入方法Fail。然后,您可以删除DefaultTraceListener并使用您自己的,或者programmaticallyconfiguration file

这看起来很麻烦,而且只有在您想要动态改变应用程序通过跟踪侦听器处理断言的方式时才是合理的。对于您始终想要失败的违规行为,请创建您自己的AssertionException课程并立即将其扔掉。

对于.NET 4.0,我会定义一下Contract.Assert方法。但是,只有在定义符号DEBUGCONTRACTS_FULL时才编译此方法。 DEBUG将无法​​在发布版本上工作,并且CONTRACTS_FULL也会启用所有其他合同检查,其中一些可能不希望出现在发布版本中。