我最近在办公室里听到过关于.Net“合同”的一些讨论但是,当我问我的一些同事时,他们不能轻易地向我解释他们的用途,甚至他们甚至是什么。
有没有人有任何资源,解释,也许有关于其用法的教程?
谢谢,
保
答案 0 :(得分:25)
代码契约是在.NET 4.0中引入的,它们提供了一种语言无关的方法来表达程序中的编码假设。
它们基本上允许您检查前置条件,后置条件和其他功能,并且可以极大地改进测试过程以及最终编写的代码质量。
来自Microsoft:
运行时检查。我们的二进制重写器通过注入合同来修改程序,合同将作为程序的一部分进行检查>执行。重写的程序提高了可测试性:每个合同都充当了oracle,为测试运行提供了通过/失败指示。自动测试工具,例如Pex,利用契约通过过滤掉不符合前提条件的无意义测试参数来生成更有意义的单元测试。
静态检查。我们的静态检查程序可以在不运行程序的情况下决定是否存在合同违规行为!它检查隐式契约,例如空引用和数组边界,以及显式契约。
文档生成。我们的文档生成器使用合同信息扩充现有的XML doc文件。还有一些可以与Sandcastle一起使用的新样式表,以便生成的文档页面包含合同部分。
了解详情:
答案 1 :(得分:17)
代码合约是对函数输入和输出执行检查的一种相对较新的方法。它们与标准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;
}