我经常遇到如下代码:
if ( items != null)
{
foreach(T item in items)
{
//...
}
}
基本上,if
条件确保仅当foreach
不为空时才会执行items
块。我想知道是否真的需要if
条件,或foreach
将处理items == null
的情况。
我的意思是,我可以简单地写一下
foreach(T item in items)
{
//...
}
不用担心items
是否为空? if
条件是多余的吗?或者这取决于items
的类型还是T
上的类型?
答案 0 :(得分:83)
您仍然需要检查if(items!= null)否则您将获得NullReferenceException。但是你可以这样做:
List<string> items = null;
foreach (var item in items ?? new List<string>())
{
item.Dump();
}
但您可能会检查它的效果。所以我仍然希望首先使用if(items!= null)。
根据Eric的Lippert建议,我将代码更改为:
List<string> items = null;
foreach (var item in items ?? Enumerable.Empty<string>())
{
item.Dump();
}
答案 1 :(得分:45)
使用C#6,您可以将新的空条件运算符与List<T>.ForEach(Action<T>)
(或您自己的IEnumerable<T>.ForEach
扩展方法)一起使用。
List<string> items = null;
items?.ForEach(item =>
{
// ...
});
答案 2 :(得分:32)
这里的实际内容应该是一个序列在第一时间几乎不应该为空。只需在所有程序中使其成为一个不变量,如果你有一个序列,它永远不会为空。它始终初始化为空序列或其他一些真正的序列。
如果序列永远不为null,那么显然你不需要检查它。
答案 3 :(得分:9)
实际上@Connect上有一个功能请求:http://connect.microsoft.com/VisualStudio/feedback/details/93497/foreach-should-check-for-null
反应非常符合逻辑:
我认为大多数foreach循环都是 写作的目的是迭代a 非空集合。如果你试试 迭代通过null你应该得到 你的例外,以便你可以解决 你的代码。
答案 4 :(得分:5)
你总是可以用空列表来测试它...但这是我在msdn网站上找到的
foreach-statement:
foreach ( type identifier in expression ) embedded-statement
如果expression的值为null,则抛出System.NullReferenceException。
答案 5 :(得分:2)
这不是超级丰富的。在运行时,项目将被转换为IEnumerable,并将调用其GetEnumerator方法。这将导致取消引用将失败的项目
答案 6 :(得分:2)
您可以将null检查封装在扩展方法中并使用lambda:
public static class EnumerableExtensions {
public static void ForEach<T>(this IEnumerable<T> self, Action<T> action) {
if (self != null) {
foreach (var element in self) {
action(element);
}
}
}
}
代码变为:
items.ForEach(item => {
...
});
如果你想只是调用一个带项目并返回void
的方法,那么可以更简洁:
items.ForEach(MethodThatTakesAnItem);
答案 7 :(得分:1)
你确实需要这个。当foreach
访问容器以设置迭代时,您将获得异常。
在幕后,foreach
使用an interface implemented on the collection class执行迭代。通用等效接口是here。
C#的foreach声明 语言(在Visual Basic中为每个语言) 掩盖了复杂性 统计员。因此,使用foreach 建议而不是直接 操纵枚举器。
答案 8 :(得分:0)
测试是必要的,因为如果集合为null,foreach将抛出NullReferenceException。尝试它实际上非常简单。
List<string> items = null;
foreach(var item in items)
{
Console.WriteLine(item);
}
答案 9 :(得分:0)
第二个会抛出NullReferenceException
消息Object reference not set to an instance of an object.
答案 10 :(得分:0)
如上所述here,您需要检查它是否为空。
不要使用计算结果为null的表达式。
答案 11 :(得分:0)
In C# 6 you can write sth like this:
// some string from file or UI, i.e.:
// a) string s = "Hello, World!";
// b) string s = "";
// ...
var items = s?.Split(new char[] { ',', '!', ' ' }) ?? Enumerable.Empty<string>();
foreach (var item in items)
{
//..
}
It's basically Vlad Bezden's solution but using the ?? expression to always generate an array that is not null and therefore survives the foreach rather than having this check inside the foreach bracket.