合同 - 如何要求集合不包含空值

时间:2015-03-11 19:57:12

标签: c# code-contracts

我的类上有一个返回List<MyType>的内部属性,我想使用静态检查来帮助我在程序集中不做任何愚蠢的操作,并可能在该集合中添加null。

我在foreach的循环变量上获得了静态警告。

  

警告149 CodeContracts:可能在null上调用方法   引用'myLoopVariable'。你期待吗?   System.Collections.Generic.List`1 + Enumerator.get_Current   返回非null?

我过去从来没有遇到任何问题我的收藏品包含空值,但是当编译器和我不同意时,它是对的,我错了,因此我希望警告消失。这是我以前从未想过的事情,当然,我可以做MyClass.MyListProperty.Add(null),所以它确实有效。

我无法在Requires使用循环变量,因为我收到错误:

  

try块中的合同部分

它让我(没有任何错误)在方法中添加Requires

Contract.Requires<ArgumentException>(Contract.ForAll<MyClass>(MyClassInstance.MyListProperty, x => x != null))

然而,这并没有导致原始警告消失,并导致另外一个警告:

  

警告149 CodeContracts:要求未经证实:   Contract.ForAll(MyClassInstance.MyListProperty,x =&gt; x!=   空)

我想知道是否有办法将逻辑放在一个地方,靠近属性定义本身。

代码契约提供了什么机制(如果有的话)来实现这个目标?

修改

我开始认为我将不得不再次私有MyListProperty,并限制对它的访问。否则,有人(我)可以添加null! (但挑战是,如何允许“受信任的”访客进行枚举?哦,我的!)

1 个答案:

答案 0 :(得分:0)

假设将得到消息,但我不确定这是否会导致性能问题,也似乎是多余的。不幸的是,如果不使用Contract.Assume,我无法摆脱静态检查器消息。

// at the beginning of your method
Contract.Requires(MyCollection != null && Contract.ForAll(MyCollection, x => x != null));
// other code
foreach(var item in MyCollection)
{
   Contract.Assume(item != null);
   // call method on item which can create a message from the static checker if the assume is not included
}