我最近听了 Kevin Hazzard 在 .Net Rocks show 570 ( http://devjourney.com/community/dotnet-rocks-show-570-with-kevin-hazzard/ )中谈论代码合同。他提到启用运行时合同检查作为一些人可能会选择使用而其他人可能不会选择使用的选项。
为什么不对代码合同使用运行时合同检查?对性能有显着的负面影响吗?其他原因?
如果禁用此功能,如何在运行时处理方法中的先决条件?
我最近听了 Kevin Hazzard 在 .Net Rocks show 570 ( http://devjourney.com/community/dotnet-rocks-show-570-with-kevin-hazzard/ )中谈论代码合同。他提到启用运行时合同检查作为一些人可能会选择使用而其他人可能不会选择使用的选项。
为什么不对代码合同使用运行时合同检查?对性能有显着的负面影响吗?其他原因?
如果禁用此功能,如何在运行时处理方法中的先决条件?
在一些非关键任务应用程序中,您可能实际上希望让错误在发布版本中滑动,而不是在用户面前抛出错误对话框。最终用户可能永远不会注意到的小错误可能会导致您的合同检查失败并损害用户体验。
在我看来,同时使用 Contracts和另一种形式的前提条件检查 - 因为您可能最终会复制您的前提条件。
使用合同检查您将迫使客户拥有 .Net Framwork 4.0 或更高版本 - 就性能而言,虽然我无法想象这是一个问题,但您最好在做出决定之前先对其进行测试或其他。
在 Code Contracts文档中,有一节介绍了如何在运行时使用 Code Contracts。最好提前决定如何在运行时使用代码契约,然后按照文档中的指南进行操作。
如果您不打算在发布版本中使用运行时检查器,那么您最好编写遗留的“if...then throw”前置条件而不是代码协定前置条件。您仍然可以在调试版本中编写后置条件和不变量,但不会在运行时检查它们。但是,它们在您的调试版本中仍然有用,用于启用代码协定的调试目的。
在许多情况下,如果您想从异常中恢复,您需要有关导致它的原因的详细信息 - 这通常涉及创建您自己的异常类并将您的详细信息证明为属性。使用最基本的示例, anArgumentOutOfRangeException
包含一个 property ActualValue
,您可以读取它并根据您获得的值决定要做什么。
使用合约时,如果您的合约失败,您只会得到一个 basic ContractException
,它是编译器生成的,并且仅包含有关合约失败的字符串形式的详细信息,可能需要一些复杂的解析才能从中提取您想要的内容- 你通常不会打扰这样做。
如果您使用自己的异常,则没有理由在运行时将合约保留在那里,因为如果它们即将失败,它们将永远无法到达 - 您只是在浪费指令。
将静态合同检查与您自己的异常检查一起使用是消除错误的最有效形式。大多数情况下,您的异常永远不会被抛出,因为您被告知如何在运行应用程序之前解决问题。