.net 有问题的系统诊断合同的有用性

.net 有问题的系统诊断合同的有用性,.net,code-contracts,.net,Code Contracts,我一直在使用新的System.Diagnostics.Contracts类,因为它一开始似乎非常有用。用于检查入站参数、返回值等的静态方法。它是一个干净的接口,可以替换许多if-then语句和内部构建的库工具 但是,在大多数运行时情况下,它似乎不太有用。据我所知,它不会抛出一个错误,所以我无法捕捉到任何东西来知道合同是否失败。它会弹出一个包含错误的对话框。如果我在一个很少有人看到的远程盒子上运行wcf服务…我怎么知道合同失败了?如果我不能捕捉到错误发生的事实,我怎么能让服务的调用者知道他们失败了

我一直在使用新的System.Diagnostics.Contracts类,因为它一开始似乎非常有用。用于检查入站参数、返回值等的静态方法。它是一个干净的接口,可以替换许多if-then语句和内部构建的库工具

但是,在大多数运行时情况下,它似乎不太有用。据我所知,它不会抛出一个错误,所以我无法捕捉到任何东西来知道合同是否失败。它会弹出一个包含错误的对话框。如果我在一个很少有人看到的远程盒子上运行wcf服务…我怎么知道合同失败了?如果我不能捕捉到错误发生的事实,我怎么能让服务的调用者知道他们失败了

抛接球已经有一段时间了,我不明白为什么合同想要绕过这个。我是不是用错了这个东西?如果是这样,那么有人会给我一个现实生活中的场景,其中运行时契约是有意义的。 肯

据我所知,它不会抛出一个错误,所以我无法捕捉到任何东西来知道合同是否失败

如果需要抛出调用代码捕获的特定异常,则应使用
Contract.Requires
方法或legacy If-then throws后跟
Contract.EndContractBlock()
。例如,当其他代码已经期望并依赖于抛出的常规异常时,您可以这样做

有关何时使用不同形式的前提条件的完整解释,请参见第5.1节:论证验证和合同

它会弹出一个包含错误的对话框

如果在项目设置的“代码契约”选项卡中取消勾选“在契约失败时断言”,则在调试时会在代码中出现问题的地方引发实际异常,而不是对话框。然而,这不是为了捕捉

抛接球已经有一段时间了,我不明白为什么合同想要绕过这个。我是不是用错了这个东西?如果是这样,那么有人会给我一个现实生活中的场景,其中运行时契约是有意义的

第7.5节:Rational for Runtime Behavior和第7.6节:ContractException of the解释了它为何以这种方式运行

其思想是,您永远不需要编写包含处理契约冲突的特定逻辑的程序。它们不应该出现在正确的程序中,并且表明需要修复的代码中存在严重错误。这类似于您应该如何避免捕获
ArgumentNullException

在不表明代码本身存在错误的异常情况下,如找不到文件时,仍应抛出常规异常。这允许调用代码适当地处理这种情况

如果我在一个很少有人看到的远程盒子上运行wcf服务…我怎么知道合同失败了

最好是在使用软件之前尽可能多地测试它,以确保它不会违反任何合同

如果您特别需要重写运行时行为,可以通过编写自己的契约运行时类来实现。有关更多信息,请参阅第7.7节:提供的自定义合同运行时类

编辑:回应下面的评论…

您说这是为了查找代码中的错误,但代码中的大多数错误来自从外部源传入的数据,而不是错误代码。软件需要两者兼而有之,记录有人传入错误数据的事实,并告诉他们传入了错误数据,以便他们能够修复它

先决条件是定义何时允许调用某个方法的契约,它意味着调用方在调用该方法时对其进行验证。运行时检查器将在调用代码中插入适当的检查,而不是方法本身。如果您有可用的静态检查器,当您在调用该方法之前未能确保先决条件时,它将向您指出


在您的情况下,处理数据的内部方法应该定义前提条件,说明它们允许什么样的数据。当数据从您无法控制的外部源传入时,您应该验证它并以通常的方式处理它;您不想为此使用代码契约。但是,例如,如果您忘记完全验证该数据,那么在调用带有前提条件的内部代码时,您将遇到违反约定的情况。这表示您自己的代码中有一个错误

,可能是因为它位于诊断名称空间中,这意味着它不应用于您的预期目的。试着看看代码契约或类似的东西。我以为这是代码契约。这是我所知道的.NET4.0中唯一的代码契约部分。(不包括WCF中的ServiceContract或DataContract…这是不同的)代码契约确实位于System.Diagnostics命名空间中。您使用的是正确的。这是一个很酷的“假设”类项目,但是基本的检查和抛出类在框架中会更有用。Rich,感谢您花时间。不过,你并没有真正证明合同的有用性。您说这是为了查找代码中的错误,但代码中的大多数错误来自从外部源传入的数据,而不是错误代码。软件需要两者兼而有之,记录有人传入错误数据的事实,并告诉他们传入了错误数据,以便他们能够修复它。合同似乎没有考虑到这一点。静态契约(编译时)对我来说很有意义。使用Diagnostics包实现的运行时契约似乎无法修复任何问题。仍在寻找用例。请检查我的更新答案以获取我的响应。回复太大,无法作为评论发布。