C# 为什么CodeContracts建议在foreach循环中进行空检查

C# 为什么CodeContracts建议在foreach循环中进行空检查,c#,code-contracts,C#,Code Contracts,我有以下代码: foreach (UIElement uiElement in list) { uiElement.SetValue(Grid.ColumnProperty, colunmn++); uiElement.SetValue(Grid.RowProperty, _uiRoot.RowDefinitions.Count - 1); _uiRoot.Children.Add(uiElement); } 它运行良好,但代码契约给了我一个警告:可能对空引用uiEle

我有以下代码:

foreach (UIElement uiElement in list)
{
    uiElement.SetValue(Grid.ColumnProperty, colunmn++);
    uiElement.SetValue(Grid.RowProperty, _uiRoot.RowDefinitions.Count - 1);
    _uiRoot.Children.Add(uiElement);
}
它运行良好,但代码契约给了我一个警告:可能对空引用uiElement调用方法


uiElement怎么可能是空的?列表是
UIElement
s的
list
,因此它应该在列表中迭代,而不使用任何空值。

列表可以包含空引用。您可以在列表中插入null。您还可以在列表中插入一个好的引用,然后稍后将其设置为null。 例如,如果我有一个人员列表,我可以有以下列表: “鲍勃”,“弗雷德”。 现在我从列表中抓取Bob,做一些事情,并将其更改为null。
列表包含引用列表,而不是项目列表。所以它指向物品所在的位置。现在,当您遍历列表时,位置0现在为null,因为Bob所在的引用现在包含null。

因为您可以在列表中放置null,即使您可能不会这样做

你能行

foreach (UIElement uiElement in list.Where(e => e != null))
{
   uiElement.SetValue(Grid.ColumnProperty, colunmn++);
   uiElement.SetValue(Grid.RowProperty, _uiRoot.RowDefinitions.Count -1);
   _uiRoot.Children.Add(uiElement);
}

您可以在listUnrelated中设置null:您不应该在过程代码中这样做。创建一个合适的ViewModel并使用数据绑定。谢谢,我喜欢linq null检查。如果您额外承诺不会在
列表中设置null
,您可以跳过开销,只使用
契约。假设(uiElement!=null)
作为循环中的第一行。