如果collection为null,为什么foreach会抛出异常

时间:2013-09-23 23:46:38

标签: c# foreach nullreferenceexception

我问的是,当你试图用foreach循环迭代的对象是null时,抛出异常的原因是什么?

例如,以下代码抛出异常:

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,你实际上想要抛出异常但是,我觉得那些是目前为止的少数,它们应该是你需要显式并检查null的情况。如下所示:

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

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

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

2 个答案:

答案 0 :(得分:6)

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

例如,假装以下代码规定了距离您住所三英里的核电站:

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

现在考虑getOverheatingCores()中是否存在导致偶尔返回null的错误。我倾向于在foreach上抛出异常,你很可能会在软件开发过程中发现它。根据您的偏好,默默地将null视为空列表,您会发现当核心崩溃时。不知道你,但我知道哪一个我更喜欢:)

答案 1 :(得分:4)

否..将foreach变为枚举器..基本上,foreach上的numbers执行此操作:

var enumerator = numbers.GetEnumerator();

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