我为什么要使用像
这样的代码合约Contract.Requires<ArgumentNullException>( x != null, "x" );
而不是旧的
if (x!=null){}
else throw...
除了简明之外还有其他好处吗?
答案 0 :(得分:14)
根据MSDN:
代码合同的好处包括:
- 改进的测试:代码合同提供静态合同验证,运行时检查和文档生成。
- 自动测试工具:您可以使用代码契约通过过滤掉不符合前提条件的无意义测试参数来生成更有意义的单元测试。
- 静态验证:静态检查程序可以在不运行程序的情况下决定是否存在任何合同违规。它检查隐式契约,例如null解除引用和数组边界,以及显式契约。
- 参考文档:文档生成器使用合同信息扩充现有XML文档文件。还有样式表可以与Sandcastle一起使用,以便生成的文档页面具有合同部分。
您的里程数可能会有所不同。我发现第三和第四(静态验证和文档)特别有趣。
换句话说,它是描述其他工具能够理解的合同(而不是像if (x!=null){}
这样的结构)的更有条理的方式。
答案 1 :(得分:9)
除了语法糖之外,Code Contracts是Microsoft的&#34; Design by Contract&#34;范例。 http://en.wikipedia.org/wiki/Design_by_contract
在设计类和操作时,它基本上是一种不同的思维方式。根据经验,DbC在测试驱动开发方面非常有效,您在编写任何业务逻辑之前基本上定义了合同并为其编写测试。
在幕后,合同合同在编译时生成类似于旧代码的代码,因此IL代码包含所有检查。
例如,班级
public class Scheduler
{
public bool ScheduleTask(string taskname, DateTime startTime, DateTime endTime)
{
Contract.Requires(!string.IsNullOrWhiteSpace(taskname));
Contract.Requires(startTime != null);
Contract.Requires(endTime != null);
return true;
}
}
会产生类似
的结果public bool ScheduleTask(string taskname, DateTime startTime, DateTime endTime)
{
__ContractsRuntime.Requires(!string.IsNullOrWhiteSpace(taskname), null, "!string.IsNullOrWhiteSpace(taskname)");
__ContractsRuntime.Requires(true, null, "startTime != null");
__ContractsRuntime.Requires(true, null, "endTime != null");
return true;
}
其中_ContractsRuntime.Requests如下所示
internal static void Requires(bool condition, string msg, string conditionTxt)
{
if (!condition)
{
__ContractsRuntime.ReportFailure(ContractFailureKind.Precondition, msg, conditionTxt, null);
}
}