在发布版本中使用System.Diagnostics.Contract

时间:2012-01-30 17:58:33

标签: c# .net contracts

我之前在StackOverflow上看过一个关于此问题的讨论,但我无法再找到它了!

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

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

1 个答案:

答案 0 :(得分:11)

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

  1. 仅在Debug版本中通过Contracts进行参数验证,而不是在Release版本中。
  2. 还在发布版本中验证。
  3. 发布版本中的自定义参数验证,仅在调试版本中的合同。
  4. 因此,至少有一种使用模式,您可以在发布版本中使用合同,至少在官方文档中是这样。

    引用:

      

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

         

    最简单地使用合同工具的方法是,如果您决定在发布版本中不需要在运行时执行参数验证(用法1)。在这种情况下,您在开发期间使用合同工具,但不在发货位上使用。请记住,您可以将合同引用程序集与发布位一起发送,以便客户端可以通过调用站点需要检查来调试其调试版本上的参数验证。

         

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

         

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

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