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

Art*_*nko 10 c# code-contracts

我有一些工厂方法

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

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

        return result;
    }
Run Code Online (Sandbox Code Playgroud)

我尝试构建项目,我得到警告:

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;
    }
Run Code Online (Sandbox Code Playgroud)

但它又向我发出警告:

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;
    }
Run Code Online (Sandbox Code Playgroud)

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

谢谢.

Jon*_*eet 16

你想要Contract.Assume:

Contract.Assume(result != null);
Run Code Online (Sandbox Code Playgroud)

来自文档:

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

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