我有一个看起来像这样的课程:
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
中的第一个元素。
为什么断言失败?
答案 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 :断言失败。)