2

我在问当您尝试使用 foreach 循环迭代的对象为空时引发异常的原因是什么?

例如,以下代码会引发异常:

public void Test()
{
    IEnumerable<int> numbers = null;

    foreach (var number in numbers)
    {
        //Do stuff
    }
}

现在修复很简单,只需在 foreach 循环之前检查 null 即可。

public void Test()
{
    IEnumerable<int> numbers = null;

    if (numbers != null)
    {
        foreach (var number in numbers)
        {
            //Do stuff
        }
    }
}

我的想法是,你可以用 foreach 循环做的所有事情,你可以只用一个常规的 for 循环来做,因此 foreach 循环基本上存在,因为它更方便编写和更易于阅读。重要的是写起来更方便。如果创建某些东西是为了方便,为什么不一路走下去,在这种情况下隐式地进行空检查。现在可能在某些情况下,如果集合为 null,您实际上希望引发异常,但是,我认为到目前为止,这些情况属于少数,它们应该是您需要明确并检查 null 的情况. 类似于以下内容:

public static void Test()
{
    IEnumerable<int> numbers = null;

    if (numbers == null)
        throw new NullReferenceException();

    foreach (var number in numbers)
    {
        //Do stuff
    }
}
4

2 回答 2

6

IMO,在这种情况下抛出异常是一件好事。否则,您可能会忘记初始化IEnumerable并运行您的代码,就好像一切都很好(实际上它并没有像您想要的那样迭代您的列表)。在大多数程序中,这个错误很快就会变得明显,但最好让你的程序崩溃而不是冒着默默地发生故障的风险。

例如,假设以下代码管理距离您居住地 3 英里外的核电站:

while (true)
{
    List<string> coresThatAreOverheating = getOverheatingCores();
    foreach (string thisCore in coresThatAreOverheating)
    {
        coolCoreDown(thisCore);
    }
}

现在考虑是否存在getOverheatingCores()导致它偶尔返回的错误null。在我倾向于foreach在 . 在你喜欢默默地把null它当作一个空列表来对待的情况下,你会发现当核事故发生时。不了解你,但我知道我更喜欢哪一个:)

于 2013-09-23T23:56:08.537 回答
4

不.. aforeach变成了一个枚举器.. 本质上, a foreachonnumbers这样做:

var enumerator = numbers.GetEnumerator();

..与任何其他调用一样,对null引用的方法调用会抛出NullReferenceException.

于 2013-09-23T23:49:27.383 回答