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

her*_*ter 9 .net c# .net-4.0 code-contracts

我打算使用新的.NET 4 Code Contracts功能进行未来的开发.这让我想知道我们是否必须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);
    }
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

Jon*_*eet 14

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

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

我强烈怀疑,如果没有指定,在"违约"超载合同,静态检测器(这目前可用于VS2010的所有版本)会抱怨,该合同可能会失败,也将建议增加合同.