Code Contracts - Precondition Failed

         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检查才可以。否则,你就会在运行时看到如下的错误信息:

 

 

对应的执行代码如下:

using 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调用,下面的代码却不会上面的错误:

    class 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未被定义的情况下也仍然可用,所以就会出现上面的错误。

 

        [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");
        }
        
        [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. "
 

参考

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值