为什么.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()方法。 当引用为空时,这将引发此异常。

但是,具有空IEnumerableIEnumerable<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?

下一篇: debugger for c++ using eclipse on mac