为什么这个合同断言不能被证明?

时间:2011-07-28 14:51:26

标签: c# .net code-contracts

我有一个看起来像这样的课程:

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"
    }
}

据我所知,Contracts拥有它需要知道result不会为空的所有信息。 bars至少包含一个元素。如果其中一个元素与SomePredicate匹配,result将是第一个这样的元素。如果没有,result将是bars中的第一个元素。

为什么断言失败?

3 个答案:

答案 0 :(得分:4)

集合bars仍可包含null的项目。如果该项目是第一项,那么result仍然可以是null

答案 1 :(得分:2)

您尚未确定或假设bars内的元素不为空。尝试:

Contract.ForAll(bars, x => x != null);

或(你的实际不变量):

Contract.Requires(bars.FirstOrDefault(x => SomePredicate(x)) != null
               || bars.First() != null);

答案 2 :(得分:1)

如果bars的第一个元素是null怎么办? ( A :断言失败。)