.Net代码合约 - 如何了解更多?

21

最近我在办公室里听到一些关于.Net“契约”的讨论,但是当我问我的一些同事时,他们都不能很容易地向我解释这些契约的作用或者它们甚至是什么。

有没有人有相关资源、解释以及使用教程呢?

谢谢,

保罗


如果有人在考虑在2019年使用代码合同,那么您可能需要重新考虑。terrajopst(我想是微软的)在2018年8月3日写道:“我们已经停止投资代码合约一段时间了。我们将其添加到.NET Core 2.0中作为兼容性努力的一部分,但我不建议使用它编写新代码。”这是从https://learn.microsoft.com/en-us/dotnet/framework/debug-trace-profile/code-contracts底部的评论部分复制的。 - Theophilus
这是对我上一条评论的更正。引用来自反馈部分底部的“已关闭”选项卡中提供的URL。该部分的URL为https://learn.microsoft.com/en-us/dotnet/framework/debug-trace-profile/code-contracts#feedback。 - Theophilus
那个讨论链接是 https://github.com/dotnet/docs/issues/6361,用于更多的讨论。https://github.com/dotnet/corefx/issues/24681 是另一个相关的链接,关于代码合同正在逐步淘汰,引用“大多数合同的静态分析最好由Roslyn Analyzers或C#8的Nullable Reference Types来处理”。 - Andy Brown
2个回答

25

代码合约是在.NET 4.0中引入的,它们提供了一种语言无关的方法来表达程序中的编码假设。

它们基本上允许您检查预先条件、后置条件和其他特性,并且可以大大改善编写的代码的测试过程和最终质量。

来自Microsoft:  

  • 运行时检查。我们的二进制重写器通过注入契约来修改程序,这些契约作为程序执行的一部分进行检查。重写的程序提高了可测试性:每个契约都充当一个oracle,给测试运行传递了一个通过/失败的指示。自动化测试工具(例如Pex)利用合约来生成更有意义的单元测试,通过过滤不满足前置条件的无意义的测试参数。

  • 静态检查。我们的静态检查器可以在甚至不运行程序的情况下决定是否存在任何契约违规!它检查隐式合约,例如null引用和数组边界,以及显式合约。

  • 文档生成。我们的文档生成器使用契约信息增强现有的XML doc文件。也有可以与Sandcastle一起使用的新样式表,以便生成的文档页面具有契约部分。

了解更多信息:


谢谢Rionmonster,这很有帮助! - Paul Gleeson

17

Code Contracts是一种相对较新的在函数输入和输出上执行检查的方式。与您标准的Assert类型检查不同的是,生成的IL会直接检查输入,检查发生在函数调用之前,并且检查输出的代码会在函数退出后进行。

这有什么用处呢?

好处在于,它可以防止您在认为函数即将返回后修改变量,从而可能引入错误。

以下是一个例子。

public void doSomething(SomeObject foo)
{
    Contract.Requires<ArgumentNullException>(foo != null);
}

现在,代码合同要求在检查之前没有任何代码。 在生成的IL中,在调用之前测试foo的值。 这是确保输入与预期相符的绝对方法。

另一个是Contract.Ensures结构。 这基本上像Requires,但作用于您的返回值。

public int doSomethingElse()
{
    Contract.Ensures(Contract.Result<int>() != 0);
    int ret = 1;
    return ret;
}

如果你的函数有多个退出路径,这将特别有用...

public int someBadFunction()
{
    Contract.Ensures(Contract.Result<int>() != 0);
    if(....)
    {
       if(....) return 2;
       if(....) return 8;
    }
    return 3;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接