c# - 代码契约和重载

标签 c# code-contracts

假设我正在编写一个实用程序库,它定义了具有两个重载的方法:

public static class MyClass
{
    public static void DoSomething(string myValue, bool myFlag)
    {
        Contract.Requires<ArgumentNullException>(myValue != null);
        CallExternalMethod(myValue);
        if(myFlag){
            AlsoCallOtherMethod(myValue);
        }        
    }

    public static void DoSomething(string myValue)
    {
        Contract.Requires<ArgumentNullException>(myValue != null);
        DoSomething(myValue, true);
    }
}

作为最佳实践,我仅在一个方法中定义逻辑,并使用重载来指定默认参数(.Net 3.5,我无法使用.Net 4 默认值参数)。

如您所见,我还使用合约验证输入。

既然逻辑只有第一个方法,那第二个Contract就没用了吗?

关于运行时检查,我知道它没有用,但是静态检查器呢?它是否足够聪明,能够理解我的模式?

最佳答案

我完全不同意BonyT's answer .

代码契约是文档和方法契约的一部分,就像类型和名称一样。用户/开发人员没有理由假设您只调用其他方法重载而没有执行其他任何操作。找出哪些契约(Contract)适用于某个方法不应该是一个猜谜游戏。如果参数或返回值有限制,请使用代码契约记录它,即使您在内部(对其他人隐藏)只是调用另一个方法。

您一定不能将代码契约视为只​​是一个断言工具:控制流运行到另一个重载,该重载检查参数,因此我不必在这里执行此操作。您必须将其视为文档。

在实践层面上:添加代码契约还会将这些契约添加到您生成的 XML 文档中。静态检查器和代码契约(Contract)编辑器扩展等工具可以向用户显示契约(Contract)。其他一些很好的论据可以找到in this related post by Pascal Cuoqthis post by Jon Skeet .

但是,从运行时的角度来看,它是多余的。至于运行时开销:大多数检查相对较小,并且不存在性能问题。某些检查可能与性能有关(最明显的是对集合、数组和枚举的检查),但可以在项目的“代码契约”属性对话框中单独禁用这些检查(例如对于发布版本)。一般来说,这同样适用于合约:您可以将检查降低到您想要的任何级别,以便在真正关键时提高性能。如果您构建合约程序集,用户仍将获得静态检查。

总结一下。指定冗余的要求和确保的缺点:

  • 相同的条件可能会检查两次或更多次
  • 由于多重检查(如果不禁用它),对性能产生微小的负面影响
  • 更多打字(但请参阅 these snippets )

专业人士:

  • 代码文档
  • 生成的 XML 文档
  • 代码用户的静态检查器按预期工作
  • 代码契约编辑器扩展有效
  • ArgumentException for Requires 发生在被调用的方法中,而不是发生在深处的某个方法中

关于c# - 代码契约和重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11556324/

相关文章:

c# - 如何将字体颜色添加到 .net 控制台应用程序?

c# - 使用 HttpClient 向 Microsoft Graph 请求用户列表时出现未经授权的问题

c# - 使用命令行解析器库的列表/数组的默认值

c# - 如何在 .NET Core 中正确使用代码契约

.net - .NET 中的代码约定、测试、断言和异常,何时使用?

C# - 无法比较数组中的两个元素

c# - 如何从 html 字符串(如编号目录)中仅提取标题(即 h2、h3、h4)?

c# - 代码合约静态分析: Prover Limitations?

c# - 是否有可能在构造函数中违反 Liskov 替换原则?

c# - 带有 ReSharper 8.2 的 VS2013 不识别代码契约(Contract)?