为什么.NET foreach循环在收集为空时抛出NullRefException?
所以我经常遇到这种情况...... Do.Something(...)
返回一个Do.Something(...)
,如下所示:
int[] returnArray = Do.Something(...);
然后,我尝试像这样使用这个集合:
foreach (int i in returnArray)
{
// do some more stuff
}
我只是好奇,为什么不能在一个空集合上运行一个foreach循环? 对我来说,看起来合乎逻辑的是,0次迭代将得到一个NullReferenceException
执行......相反,它会抛出一个NullReferenceException
异常。 任何人都知道为什么会这样?
这很烦人,因为我正在处理那些不清楚它们返回的API,所以我最终得到if (someCollection != null)
无处不在...
编辑:谢谢大家解释说foreach
使用GetEnumerator
,如果没有枚举器得到,则foreach将失败。 我想我问为什么语言/运行时不能或不会执行空检查,然后抓住枚举器。 在我看来,这种行为仍然是明确的。
那么简短的答案就是“因为这是编译器设计者设计它的方式。” 不过,实际上,你的集合对象是空的,所以编译器无法让枚举器遍历集合。
如果您确实需要这样做,请尝试使用空合并运算符:
int[] array = null;
foreach (int i in array ?? Enumerable.Empty<int>())
{
System.Console.WriteLine(string.Format("{0}", i));
}
一个foreach
循环调用GetEnumerator
方法。
如果集合为null
,则此方法调用NullReferenceException
。
返回null
是不好的做法; 你的方法应该返回一个空的集合。
对一个集合的空集合和空引用有很大的区别。
当你使用foreach
,在内部,这是调用IEnumerable的GetEnumerator()方法。 当引用为空时,这将引发此异常。
但是,具有空IEnumerable
或IEnumerable<T>
是完全有效的。 在这种情况下,foreach不会“遍历”任何东西(因为集合是空的),但它也不会抛出,因为这是一个非常有效的场景。
编辑:
就个人而言,如果你需要解决这个问题,我会推荐一个扩展方法:
public static IEnumerable<T> AsNotNull<T>(this IEnumerable<T> original)
{
return original ?? Enumerable.Empty<T>();
}
然后你可以打电话给:
foreach (int i in returnArray.AsNotNull())
{
// do some more stuff
}
链接地址: http://www.djcxy.com/p/75155.html
上一篇: Why does .NET foreach loop throw NullRefException when collection is null?