编程语言
首页 > 编程语言> > c# – 如何在不失去延迟评估优势的情况下使用代码契约来检查Lazy的值?

c# – 如何在不失去延迟评估优势的情况下使用代码契约来检查Lazy的值?

作者:互联网

我的代码看起来像这样:

public class Foo
{
    private readonly Lazy<string> lazyBar;

    public Foo()
    {
        lazyBar = new Lazy<string>(() => someExpression);
    }

    public string Bar
    {
        get { return lazyBar.Value; }
    }

    public void DoSomething()
    {
        Contract.Requires(Bar != null); // This evaluates Bar, but all I really require is that WHEN Bar is evaluated, it is not null.

        ...
    }
}

现在,每个地方都调用DoSomething,我们还必须证明Bar不是null.但是不会检查这个消除懒惰评估的好处吗?另外,我们不应该避免在合同中产生副作用吗?

是否有可能证明someExpression在没有评估的情况下不会解析为null?

解决方法:

代码契约对Lazy< T>没有足够的了解.为了在原始lambda和你得到的结果之间建立连接.

你真正希望能够声明的(对于Lazy< T>)是任何关于lambda的返回值的契约也都持有Value值,但是目前这样的元级契约是不可能的.

你可以做的是将someExpression移动到一个方法中,然后得到一个得到的Contract.Ensures!= null.如果这种情况不成立,这将警告你.然后,您可以将Invariant放在结果上; lazyBar.Value!= null.这意味着它实际上并不是懒惰,但对于您的发布代码,您可以使用CC在ReleaseRequires模式下构建,并且这些类型的检查将被消除(在手册中读取合同执行的不同“级别”是高度的推荐的!)

标签:c,net,lazy-loading,code-contracts
来源: https://codeday.me/bug/20190530/1186471.html