在Release版本中使用System.Diagnostics.Contract

本文关键字:System Diagnostics Contract Release 版本 | 更新日期: 2023-09-27 18:21:50

我之前在StackOverflow上看到一个线程对此进行了一些讨论,但我无法再次找到它!

我很想知道System.Diagnostics.Contract类是否应该在"真实代码"中使用,即生产代码的发布版本?我之所以这么问,是因为根据命名空间描述,Contract似乎是为了调试或分析目的。

它似乎是一个有用的库,其中功能的前/后条件很重要,并且可能会避免编写大量if/then/else检查的一些工作,所以如果是这样的话,核心库中有其他选择吗?

在Release版本中使用System.Diagnostics.Contract

文档的第5.1节(参数验证和合同)详细介绍了您可能考虑使用合同的三种主要使用模式:

  1. 仅在调试生成中通过协定进行参数验证,而不在发布生成中
  2. 在发布版本中也进行验证
  3. 发布版本中的自定义参数验证,仅调试版本中的合同

因此,至少有一种使用模式可以在Release构建中使用Contracts,至少在官方文档中是这样。

报价:

在您开始在自己的代码中使用契约之前,您需要做出一些决定,这些决定会影响哪些契约形式用于参数验证以及在哪里使用(见图2)。请注意,您可以为您生产的每个托管组件(每个项目)独立地做出这些决策:

契约工具的最简单用法是,如果您决定在版本构建的运行时不需要执行参数验证(用法1)。在这种情况下,您可以在开发过程中使用契约工具,但不使用已交付的部分。请记住,您可以将合同引用程序集与发布位一起发送,这样客户端就可以通过调用站点需求检查在其调试构建中对您的参数验证进行运行时检查。

如果您在发布版本中需要参数验证,第二种最简单的方法是在所有版本中启用合同检查(用法2)。因此,您可以利用这些工具来生成条件的运行时字符串,并为您执行契约继承。您可以选择为参数验证生成特定的异常,或者使用默认的ContractException。在发布版本中使用契约工具的风险在于,您依赖的工具尚未达到生产质量级别

最棘手的组合是,当您希望在发布版本中进行参数验证,但您只在调试版本中使用约定工具进行运行时检查,而不在发布版本(用法3)。在这种情况下,您必须继续以现有的方式编写参数验证,即使用if-then-throw语句(我们称之为legacy requires)。如果您希望这些是工具可发现的,请在它们之后添加其他约定(如确保),或者如果没有其他约定,则使用Contract.EndContractBlock()。请注意,由于您在版本构建中没有使用运行时检查工具,因此您不会获得任何契约的继承,并且您必须手动在重写和接口实现上重复您的遗留要求。对于接口和抽象方法,如果您使用正常的需求编写合约类并确保表单,那么您仍然可以获得最大的好处,这样您就可以在调试构建中进行检查,并且它们出现在合约引用程序集中,因此对依赖项目和静态检查程序都可见。

这也暗示了只使用框架的其他部分的替代方案:使用if-then-throw的通常方式。