Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果集合为null,为什么foreach抛出异常_C#_Foreach_Nullreferenceexception - Fatal编程技术网

C# 如果集合为null,为什么foreach抛出异常

C# 如果集合为null,为什么foreach抛出异常,c#,foreach,nullreferenceexception,C#,Foreach,Nullreferenceexception,我想问的是,当您试图用foreach循环迭代的对象为null时,抛出异常的原因是什么 例如,以下代码引发异常: public void Test() { IEnumerable<int> numbers = null; foreach (var number in numbers) { //Do stuff } } 公共无效测试() { IEnumerable number=null; foreach(数值中的变量编号) { //做

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

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

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

    foreach (var number in numbers)
    {
        //Do stuff
    }
}
公共无效测试()
{
IEnumerable number=null;
foreach(数值中的变量编号)
{
//做事
}
}
现在修复非常简单,只需在foreach循环之前检查null

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

    if (numbers != null)
    {
        foreach (var number in numbers)
        {
            //Do stuff
        }
    }
}
公共无效测试()
{
IEnumerable number=null;
如果(数字!=null)
{
foreach(数值中的变量编号)
{
//做事
}
}
}
我的想法是,你可以用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
    }
}
公共静态无效测试()
{
IEnumerable number=null;
如果(数字==null)
抛出新的NullReferenceException();
foreach(数值中的变量编号)
{
//做事
}
}

否。。一个
foreach
被转换成一个枚举器。。基本上,
numbers
上的
foreach
执行以下操作:

var enumerator = numbers.GetEnumerator();

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

IEnumerable,并以一切正常的方式运行代码(实际上它并没有像您希望的那样在列表中迭代)。在大多数程序中,这个错误很快就会变得明显,但最好是让程序崩溃,而不是冒着无声故障的风险

例如,假设以下代码规定了距离您居住的道路三英里处的核电站:

while (true)
{
    List<string> coresThatAreOverheating = getOverheatingCores();
    foreach (string thisCore in coresThatAreOverheating)
    {
        coolCoreDown(thisCore);
    }
}
while(true)
{
列出Coresthatarehousing=GetOverthingCores();
foreach(将此Core串入过热的Core中)
{
冷却堆芯(thisCore);
}
}

现在考虑在代码> > GoOutHealTeCo()/代码>中是否有一个错误,导致它偶尔返回<代码> null < /代码>。在我倾向于在

foreach
上抛出异常的情况下,您很可能会在软件开发过程中发现这一点。如果你喜欢默默地将
null
视为一个空列表,那么当发生核熔毁时,你会发现这一点。我不知道你的情况,但我知道我更喜欢哪一个:)

这个问题真的没有正确的答案。“为什么功能是这样的?”这类问题无法真正回答。也就是说,如果您的目标是枚举一个集合,而该集合为null,那么我希望出现一个异常。for循环也会发生同样的情况(只要访问Count/Length属性)。我认为,当你想要例外的时候,大多数人都是,而不是少数人。首先,这个问题主要是关于意见的,所以应该结束。其次,在语言发展的这个后期阶段,我们的观点并不重要,因为从第一天开始就是这样。@Tom:
null
的存在是为了达到一个特定的目的:表示“没有数据”。通过忽略你建议的NULL,你违反了这个目的。我认为它比隐藏可能的编程错误要好得多(我认为NULL在很多情况下是一个编码错误,并且使用ReSurps<代码> [NoTnLo] < /COD>遍历;-)。如果语义是必需的,那么使用像
foreach(blah??Enumerable.Empty()中的var b){..}
这样的构造很容易。@Tom:这是一个意见问题。如果我想显式地避免它,而不是让该方法抛出异常并在其他地方处理它,那么我个人会觉得非常不方便。如果它以静默方式失败,我将不得不在所有地方添加
null
检查,以查找错误条件,否则这些错误条件将被发现。在所有条件相同的情况下,编译器最好不要为开发人员做太多的思考。注意,这并不能真正回答这个问题,尽管-可以添加空检查,并且避免了此调用。(也就是说,没有真正的方法来回答这个问题…)我投了你一票,但作为魔鬼代言人,由于枚举数是从编译器的构造中出现的,因此确实可能存在一个返回空枚举数的nullity检查。这是真的。。但希望它能向OP指出这里到底发生了什么。。并不是说它只是一个随机的nullref。@Tom因为“它就是这样定义的”。并不是说不可能;很简单,事情不是这样的。我担心有一天编译器会那样喂你。我同意。嘈杂的一次性完全停止故障比无声的正在进行的未被注意的故障要好。您能举一个例子说明什么时候空案例不能像空收集案例一样处理,因为它会导致意外的结果吗?这是假设foreach循环在null情况下不会抛出和异常。@Tom:编辑了我的答案,以包含一个示例。这是一个非常好的示例。感谢您花时间提出它,因为现在每次我用空检查包围foreach循环时,我都会记住它。没问题,很高兴它有所帮助。只有当您自己编写的代码可能已将列表设置为
null
时,才应该执行类似的
null
检查。否则,不要人为地清除意外错误