如何使代码契约认为变量不为空?

时间:2011-09-05 06:13:40

标签: c# code-contracts

我有一些工厂方法

    public T Create<T> () where T : class 
    {
        Contract.Ensures(Contract.Result<T>() != null);

        T result = this.unityContainer.Resolve<T>();

        return result;
    }

我尝试构建项目时收到警告:

CodeContracts:确保未经证实:Contract.Result()!= null

我知道IUnityContainer接口没有任何合约,因此Code Contracts认为varible可能为null,并且无法证明Create()将返回非null结果。

在这种情况下,我如何使代码合约相信结果变量不为空?

我首先尝试调用Contract.Assert

    public T Create<T> () where T : class 
    {
        Contract.Ensures(Contract.Result<T>() != null);

        T result = this.unityContainer.Resolve<T>();

        Contract.Assert(result != null);

        return result;
    }

但它又向我发出警告:

CodeContracts:断言未经证实

我尝试检查null,这使得所有警告都消失了:

    public T Create<T> () where T : class 
    {
        Contract.Ensures(Contract.Result<T>() != null);

        T result = this.unityContainer.Resolve<T>();

        if (result == null)
        {
            throw new InvalidOperationException();
        }

        return result;
    }

但我不确定这是手动抛出异常的好方法。可能有一些方法只能使用代码合约来解决问题吗?

谢谢。

3 个答案:

答案 0 :(得分:16)

我想你想要Contract.Assume

Contract.Assume(result != null);

来自文档:

  

指示代码分析工具假设指定的条件为真,即使它不能被静态证明永远为真。

如果您正确配置了重写器,这仍将在执行时验证结果。

答案 1 :(得分:-1)

if((result ?? 0) == 0){}

为了使其更清晰(可读),您可以定义扩展方法。

修改

@allentracks答案对您的问题更准确

答案 2 :(得分:-1)

 public T Create<T> () where T : class, new()
    {
        // do what you like...

        return result ?? new T();
    }