【问题标题】:Use of System.Diagnostics.Contract in Release builds在发布版本中使用 System.Diagnostics.Contract
【发布时间】:2012-02-22 12:24:42
【问题描述】:

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

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

这似乎是一个有用的库,其中功能的前置/后置条件很重要,并且可以避免编写大量 if/then/else 检查的一些工作,所以如果是这种情况,在核心库?

【问题讨论】:

  • 请不要在标题前加上“C#”之类的前缀。这就是标签的用途。

标签: c# .net contracts


【解决方案1】:

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

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

因此,至少有一种使用模式可以在发布版本中使用合同,至少就官方文档而言。

引用:

在您开始在自己的代码中使用合约之前,您需要做出一些决定,这些决定会影响用于参数验证的合约形式和位置(参见图 2)。请注意,您可以为您生成的每个托管程序集(每个项目)独立做出这些决定:

如果您决定不需要在发布版本的运行时执行参数验证,则合约工具的最简单用途是(用法 1)。在这种情况下,您在开发过程中使用合约工具,而不是在交付的比特上。请记住,您可以将合同参考程序集与您的发布位一起发布,以便客户可以通过调用站点需要检查在其调试版本中获得参数验证的运行时检查。

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

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

这也暗示了仅使用框架的其他部分的替代方法是:使用 if-then-throw 的常用方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-01
    • 2011-06-18
    • 1970-01-01
    • 1970-01-01
    • 2012-09-27
    • 2013-05-20
    • 1970-01-01
    • 2016-01-02
    相关资源
    最近更新 更多