为什么.NET foreach循环抛出NullRefException当集合为空?抛出、为空、NET、foreach

2023-09-02 01:39:55 作者:-/一篇优雅的分手信

所以,我经常碰到这种情况......其中 Do.Something(...)返回一个空集,像这样:

So I frequently run into this situation... where Do.Something(...) returns a null collection, like so:

int[] returnArray = Do.Something(...);

于是,我尝试使用此集合像这样:

Then, I try to use this collection like so:

foreach (int i in returnArray)
{
    // do some more stuff
}

我只是好奇,为什么就不能对空的集合foreach循环操作?这似乎是合乎逻辑,我认为0次迭代可以得到一个空集执行......相反,它抛出一个的NullReferenceException 。任何人都知道这可能是为什么?

I'm just curious, why can't a foreach loop operate on a null collection? It seems logical to me that 0 iterations would get executed with a null collection... instead it throws a NullReferenceException. Anyone know why this could be?

这是恼人的,因为我的工作与空气污染指数都不清楚究竟是什么回报,所以我结束了如果(someCollection!= NULL)无处不在......

This is annoying as I'm working with APIs that aren't clear on exactly what they return, so I end up with if (someCollection != null) everywhere...

编辑:谢谢大家解释的foreach 使用的GetEnumerator ,如果有没有枚举得到,在foreach会失败。我想我问为什么的语言/运行时不能或不敛枚举之前做一个空检查。在我看来,该行为仍然会被很好的定义。

Thank you all for explaining that foreach uses GetEnumerator and if there is no enumerator to get, the foreach would fail. I guess I'm asking why the language/runtime can't or won't do a null check before grabbing the enumerator. It seems to me that the behavior would still be well defined.

推荐答案

嗯,简单的答案是因为这是编译器设计师设计的方式。事实上,虽然您的收藏对象为空,那么有没有办法让编译器通过采集获得枚举循环。

Well, the short answer is "because that's the way the compiler designers designed it." Realistically, though, your collection object is null, so there's no way for the compiler to get the enumerator to loop through the collection.

如果你真的需要做这样的事情,尝试空合并运算符:

If you really need to do something like this, try the null coalescing operator:

    int[] array = null;

    foreach (int i in array ?? new int[0])
    {
        System.Console.WriteLine(string.Format("{0}", i));
    }