I have code that looks something like this:
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.
...
}
}
Now, every place DoSomething
is called, we must also prove that Bar
is not null. But won't checking for this eliminate the benefit of lazy evaluation? Additionally, aren't we supposed to avoid side-effects in our contracts?
Is it possible to prove that someExpression
will not resolve to null, without evaluating it?
Code Contracts doesn't have enough insight into Lazy<T>
in order to make the connection between the original lambda and the result you get back.
What you really want to be able to state (for Lazy<T>
) is that any contracts that hold about the lambda's return value also hold about the Value
value, but meta-level contracts like this aren't possible at the moment.
What you could do is move someExpression
into a method and then have a Contract.Ensures
that result != null
. This will then warn you if this condition does not hold. You can then put an Invariant
onto the result; lazyBar.Value != null
. This will mean that it isn't actually lazy, but for your release code you can build with CC in ReleaseRequires
mode and these types of check will be eliminated (having a read in the manual of the different 'levels' of contract enforcement is highly recommended!)