Code Contracts 是微软对 Programming By Contract 的实现,.NET Framework 4.0和4.5都提供了相应的类库支持。在mscorelib.dll的System.Diagnostics.Contracts 名字空间下定义了Contract类,它包含了一组静态方法用来定义各种Contract,例如:Contract.Requires, Contract.Ensures等 。但是,光有这些定义Contract的代码还是不够的,你还有在你的工程中启用Runtime或者是Static Contract检查才可以。否则,你就会在运行时看到如下的错误信息:
对应的执行代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19using System; using System.Diagnostics.Contracts; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Divide(12, 1); } static int Divide(int number, int divisor) { Contract.Requires<InvalidCastException>(divisor != 0); return number / divisor; } } }
看了很多遍,感觉这段错误提示是相当难懂,让人不知到底是为什么会有这个错误,该如何修复。经过多次实验以及在网上搜索到信息,才搞明白最关键的部分要通过选择 'Enable Runtime Contract Checking' 来定义 CONTRACTS_FULL。可是,同样是使用Contract.Requires调用,下面的代码却不会上面的错误:
1
2
3
4
5
6
7
8
9
10
11
12
13class Program { static void Main(string[] args) { Divide(12, 1); } static int Divide(int number, int divisor) { Contract.Requires(divisor != 0); return number / divisor; } }
看来问题关键在于 Contract.Requires()和 Contract.Requires<>() 方法的定义是不一样的。通过.NET Reflector,可以进一步看清两者是如何定义的。 Requires()上定义了 [ConditionalAttribute("CONTRACTS_FULL")] 属性,这样编译器就可以根据CONTRACTS_FULL标识是否定义来决定Requires()是否可用;而Requires<>()没有该属性,所以它在CONTRACTS_FULL未被定义的情况下也仍然可用,所以就会出现上面的错误。
1
2
3
4
5
6[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), Conditional("CONTRACTS_FULL"), __DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public static void Requires(bool condition) { AssertMustUseRewriter(ContractFailureKind.Precondition, "Requires"); }
1
2
3
4
5
6[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), __DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public static void Requires<TException>(bool condition) where TException: Exception { AssertMustUseRewriter(ContractFailureKind.Precondition, "Requires<TException>"); }
这也是问什么在Requires<>()的文档中重点强调了 - " You must turn on run-time checking to use theRequires method. If run-time checking is turned off, the process will be terminated. To obtain the tools for runtime checking, seeCode Contracts on the MSDN DevLabs Web site. "
参考
-
Code Contracts
-
Code Contracts Settings in Visual Studio 2010
最后
以上就是喜悦睫毛膏最近收集整理的关于Code Contracts - Precondition Failed的全部内容,更多相关Code内容请搜索靠谱客的其他文章。
发表评论 取消回复