代码契约:我们是否必须在委托方法中冗余地指定Contract.Requires(…)语句?

我打算使用新的.NET 4 Code Contractsfunction进行未来的开发。 这让我想知道是否必须在一系列方法中冗余地指定等效的Contract.Requires(...)语句。

我认为一个代码示例胜过千言万语:

  public bool CrushGodzilla(string weapon, int velocity) { Contract.Requires(weapon != null); // long code return false; } public bool CrushGodzilla(string weapon) { Contract.Requires(weapon != null); // specify contract requirement here // as well??? return this.CrushGodzilla(weapon, int.MaxValue); } 

对于运行时检查它并不重要,因为我们最终总是会遇到需求检查,如果失败我们会收到错误。

但是,当我们再次在第二次超载中没有指定合同要求时,这被认为是不好的做法吗?

此外,还将具有编译时检查的function ,并且还可能设计代码合同的时间检查 。 在Visual Studio 2010中,它似乎尚不适用于C#,但我认为有一些类似Spec#的语言已经可以使用。 当我们编写代码来调用这样的方法并且我们的参数当前可以或将为null时,这些引擎可能会给我们提示。

所以我想知道这些引擎是否总是会分析一个调用堆栈,直到找到一个目前不满意的合同方法?

此外, 在这里我了解了Contract.Requires(...)Contract.Assume(...)之间的区别 。 我想在这个问题的背景下也要考虑差异呢?

我认为最佳做法是在每个公共方法上指定所有合同。 合同不仅仅是“得到检查的东西” – 它也是有效的文档。 如果你调用一个方法但不知道应用了什么合同,那么将合同失败降低是很奇怪的:这会暗示你正在调用的方法中的错误,而不是你的方法。

请注意,如果您在整个项目中使用C#4,则可以考虑使用可选参数和命名参数来避免这么多重载。 当然,如果您需要从不支持它们的语言调用代码,那么这没有用。

我强烈怀疑如果你没有在“默认”超载中指定合同,静态检查器(现在可用于所有版本的VS2010 )会抱怨合同可能会失败,并且还会建议添加合同。

此外,还将具有编译时检查的function ,并且还可能设计代码合同的时间检查 。 在Visual Studio 2010中,C#似乎尚不可用……

它可用,但要工作,你必须使用VS2010 旗舰版。

警告 :这有点推测,但从我学到的东西看起来似乎是正确的;

您需要手动通过方法传播约束,就像您所做的那样。

代码合约可以从方法外部看到的唯一信息就是您所说的。 它可以检查方法中的假设和断言,但此分析不会传播。 换句话说,CC无法“透视”您的方法,因此它不会自动知道CrushGodzilla(string)将要求weapon非空。

如果使用静态分析,它将在CrushGodzilla(string)执行检查,并使用有关CrushGodzilla(string,int)外部信息实现weapon不能为null,并且它将建议您添加Requires non-null前提条件。 (不传播的事实是,这些知识不会用于分析程序的其余部分。)

尽管看过,我还没有真正找到静态分析仪的任何文件。