为什么这个合约断言不能被证明?
本文关键字:不能 证明 断言 为什么 | 更新日期: 2023-09-27 18:03:55
我有一个类,看起来像这样:
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
的第一个元素。
为什么断言失败?
集合bars
仍然可以包含null
项。如果该项目是第一项,那么result
仍然可以是null
。
您没有确保或假设bars
内部的元素不为空。试一试:
Contract.ForAll(bars, x => x != null);
或者(实际的不变量):
Contract.Requires(bars.FirstOrDefault(x => SomePredicate(x)) != null
|| bars.First() != null);
如果bars
的第一个元素是null
呢?(A:断言失败)