是否在foreach(item中的T item)之前是多余的(items!= null)?

我经常遇到如下代码:

if ( items != null) { foreach(T item in items) { //... } } 

基本上, if条件确保只有在items不为null时才会执行foreach块。 我想知道如果条件是真的需要,或者foreach将处理的情况下,如果items == null

我的意思是,我可以简单写一下吗?

 foreach(T item in items) { //... } 

而不用担心items是否为空? if条件是多余的? 或者这取决于itemstypes ,或者也可能在T

你仍然需要检查(items!= null)否则你将得到NullReferenceException。 不过你可以这样做:

 List<string> items = null; foreach (var item in items ?? new List<string>()) { item.Dump(); } 

但你可能会检查它的性能。 所以我还是喜欢if(items!= null)。

基于Eric的Lippertbuild议,我将代码更改为:

 List<string> items = null; foreach (var item in items ?? Enumerable.Empty<string>()) { item.Dump(); } 

这里真正的外卖应该是一个序列应该几乎永远不会是空的 。 简单地说,如果你有一个序列,它就不会是空的。 它始终被初始化为空序列或其他真正的序列。

如果一个序列永远不是空的,那么显然你不需要检查它。

使用C#6,您可以将新的null条件运算符与List<T>.ForEach(Action<T>) (或您自己的IEnumerable<T>.ForEach扩展方法)一起使用。

 List<string> items = null; items?.ForEach(item => { // ... }); 

实际上这个@Connect上有一个function请求: http : //connect.microsoft.com/VisualStudio/feedback/details/93497/foreach-should-check-for-null

而且这个回应非常合乎逻辑:

我认为大多数foreach循环都是为了迭代非空集合而编写的。 如果你尝试迭代null,你应该得到你的exception,以便你可以修复你的代码。

你总是可以testing一个空列表…但这是我在msdn网站上find的

 foreach-statement: foreach ( type identifier in expression ) embedded-statement 

如果expression式的值为null,则引发System.NullReferenceException。

您可以在扩展方法中封装空检查并使用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); 

这不是过分的。 在运行时,项目将被转换为IEnumerable,并且它的GetEnumerator方法将被调用。 这将导致失败的项目解引用

你确实需要这个。 当foreach访问容器来设置迭代时,你会得到一个exception。

在下面, foreach使用集合类上实现的接口来执行迭代。 通用的等价接口在这里 。

C#语言的foreach语句(对于Visual Basic中的每个语句)都隐藏了枚举器的复杂性。 因此,推荐使用foreach而不是直接操作枚举器。

testing是必要的,因为如果集合为null,foreach将抛出一个NullReferenceException。 这实际上很简单,尝试一下。

 List<string> items = null; foreach(var item in items) { Console.WriteLine(item); } 

第二个会抛出一个NullReferenceException ,消息Object reference not set to an instance of an object.

如上所述,您需要检查它是否为空。

不要使用计算结果为null的expression式。

在C#6中,你可以这样写:

 // some string from file or UI, ie: // a) string s = "Hello, World!"; // b) string s = ""; // ... var items = s?.Split(new char[] { ',', '!', ' ' }) ?? Enumerable.Empty<string>(); foreach (var item in items) { //.. } 

这基本上是弗拉德Bezden的解决scheme,但使用?? expression式总是生成一个不为null的数组,因此可以在foreach中生存,而不是在foreach括号中进行检查。