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