C# 契约-如何要求集合不包含空值

C# 契约-如何要求集合不包含空值,c#,code-contracts,C#,Code Contracts,我的类上有一个内部属性,它返回List,我希望使用静态检查来帮助我在程序集中不做任何愚蠢的事情,并可能向该集合添加null 我在属性上的foreach的循环变量上得到这个静态警告 警告149 CodeContracts:可能在null上调用方法 引用“myLoopVariable”。你希望这样吗 System.Collections.Generic.List`1+枚举器.get_Current 返回非空 我过去从未遇到过包含null的集合的任何问题,但是当编译器和我不同意时,它是对的,我是错的,

我的类上有一个内部属性,它返回
List
,我希望使用静态检查来帮助我在程序集中不做任何愚蠢的事情,并可能向该集合添加null

我在属性上的
foreach
的循环变量上得到这个静态警告

警告149 CodeContracts:可能在null上调用方法 引用“myLoopVariable”。你希望这样吗 System.Collections.Generic.List`1+枚举器.get_Current 返回非空

我过去从未遇到过包含null的集合的任何问题,但是当编译器和我不同意时,它是对的,我是错的,因此我希望警告消失。这是我以前从未想到过的,而且我可以做
MyClass.MyListProperty.Add(null)
,因此它确实有效

我不能在使用循环变量时执行
Requires
,因为我得到了错误:

try块中的合同段

它允许我(没有任何错误)向方法中添加
Requires

Contract.Requires<ArgumentException>(Contract.ForAll<MyClass>(MyClassInstance.MyListProperty, x => x != null))
Contract.Requires(Contract.ForAll(MyClassInstance.MyListProperty,x=>x!=null))
然而,这并没有导致最初的警告消失,也导致了额外的警告:

警告149编码合同:需要未经证实的: Contract.ForAll(MyClassInstance.MyListProperty,x=>x= 空)

我想知道是否有一种方法可以把逻辑放在一个地方,靠近属性定义本身

代码契约提供了什么机制(如果有的话)来实现这一点

编辑:


我开始认为我必须再次将
MyListProperty
设为私有,并限制对它的访问。否则,有人(我)可以添加一个
null
!(但问题是,如何允许“受信任”的访问者进行枚举?哦,天哪!)

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

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

我假设“循环变量”不在方法范围内?@PeterRitchie,它是在循环声明中声明的。它可以在方法级别声明。你的想法是什么?
要求
就我所知处于方法的顶端……但是,我认为这并不能真正解决你要做的事情。@toddmo-我在下面提供了3种可能的解决方案,每种都应该很好,而不是
可枚举。所有的
。前者至少有一点机会使用静态检查器,后者肯定不会。不过,即使有了这种变化,我也不乐观。我更新了我的问题,以显示当我尝试这样做时发生了什么。我还不知道“需要未经证实”是什么意思。我实施错了吗?2.如果我在属性体中使用
确保
,会关闭警告但仍然允许空值吗?3.与#2相同的问题。@toddmo我错了,这是因为如果使用支持字段,它的可见性比属性getter本身低,因此无法工作。我想知道你在努力完成什么,我只是在玩弄它,我会试着看看我是否能找到一些东西,除非有人打败我。祝你好运,上帝保佑,谢谢你Again@toddmo-我更新了答案,但我个人不喜欢结果代码。它确实消除了静态检查器创建的消息。