I have a class that looks something like this:
class Foo
{
private IEnumerable<Bar> bars;
...
private void DoSomething()
{
Contract.Requires(bars != null);
Contract.Requires(bars.Any());
Bar result = bars.FirstOrDefault(b => SomePredicate) ?? bars.First();
Contract.Assert(result != null); // This asserts fails the static checker as "cannot be proven"
}
}
As far as I can tell, Contracts has all the information it needs to know that result
will not be null. bars
has at least one element in it. If one of those elements matches SomePredicate
, result
will be the first such element. If not, result
will be the first element in bars
.
Why does the assertion fail?
You haven't ensured or assumed that the elements inside of bars
are not null. Try:
Contract.ForAll(bars, x => x != null);
Or (your actual invariant):
Contract.Requires(bars.FirstOrDefault(x => SomePredicate(x)) != null
|| bars.First() != null);