Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.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# Foreach对不为null的IEnumerable with元素抛出NullReferenceException_C#_.net_Exception_Nullpointerexception - Fatal编程技术网

C# Foreach对不为null的IEnumerable with元素抛出NullReferenceException

C# Foreach对不为null的IEnumerable with元素抛出NullReferenceException,c#,.net,exception,nullpointerexception,C#,.net,Exception,Nullpointerexception,我在代码中遇到了与下面代码中所示类似的情况。问题在于,出于某种原因,在foreach循环中迭代会抛出NullReferenceException 我的问题是,为什么会发生这种情况 如果我自己创建一个返回空元素的迭代器,foreach处理它,然后简单地打印出空行 以下代码的结果是:test,test,NullReferenceException 这就是问题所在: listOfA.SelectMany(x=>x.NestedCollection) 您的第二个NestedA实例没有NestedCol

我在代码中遇到了与下面代码中所示类似的情况。问题在于,出于某种原因,在foreach循环中迭代会抛出
NullReferenceException

我的问题是,为什么会发生这种情况

如果我自己创建一个返回空元素的迭代器,
foreach
处理它,然后简单地
打印出
空行

以下代码的结果是:test,test,NullReferenceException

这就是问题所在:

listOfA.SelectMany(x=>x.NestedCollection)
您的第二个
NestedA
实例没有
NestedCollection
,因此它正在尝试查找“空引用中的所有项”。如果手动执行此操作,则会出现完全相同的问题:

var nestedA=new nestedA();
//这将引发异常,因为nestedA.NestedCollectoin为null
foreach(nestedA.NestedCollection中的变量nestedB)
{
}
对此最简单的修复方法是将
NestedCollection
设置为只读属性,但首先初始化它:

public List NestedCollection{get;}=new List();
然后,您需要修改第一个
NestedA
的初始化以使用集合初始值设定项:

newnesteda
{
嵌套集合=
{
新嵌套的b{Test=“Test”},
新嵌套b{Test=“Test”}
}
}
如果您不想这样做,您可以更改
SelectMany
呼叫:

var listOfB=listOfA.SelectMany(x=>x.NestedCollection??Enumerable.Empty())
这就是问题所在:

listOfA.SelectMany(x=>x.NestedCollection)
您的第二个
NestedA
实例没有
NestedCollection
,因此它正在尝试查找“空引用中的所有项”。如果手动执行此操作,则会出现完全相同的问题:

var nestedA=new nestedA();
//这将引发异常,因为nestedA.NestedCollectoin为null
foreach(nestedA.NestedCollection中的变量nestedB)
{
}
对此最简单的修复方法是将
NestedCollection
设置为只读属性,但首先初始化它:

public List NestedCollection{get;}=new List();
然后,您需要修改第一个
NestedA
的初始化以使用集合初始值设定项:

newnesteda
{
嵌套集合=
{
新嵌套的b{Test=“Test”},
新嵌套b{Test=“Test”}
}
}
如果您不想这样做,您可以更改
SelectMany
呼叫:

var listOfB=listOfA.SelectMany(x=>x.NestedCollection??Enumerable.Empty())

SelectMany的实现如下所示:

公共静态IEnumerable SelectMany(
这是一个数不清的来源,
Func选择器)
{
if(source==null)
抛出错误。ArgumentNull(nameof(source));
if(选择器==null)
抛出错误.ArgumentNull(nameof(selector));
返回可枚举的。SelectManyIterator(源,选择器);
}
私有静态IEnumerable SelectManyIterator(
IEnumerable来源,
Func选择器)
{
foreach(源中的TSource source1)
{
foreach(TResult result in selector(source1))//错误在这里抛出
收益结果;
}
}

注意注释行。
选择器(source1)
将为第二个
NestedA
项返回null,此行将尝试获取null项的枚举数(
foreach
)。这就是出现错误的原因。

SelectMany的实现如下所示:

公共静态IEnumerable SelectMany(
这是一个数不清的来源,
Func选择器)
{
if(source==null)
抛出错误。ArgumentNull(nameof(source));
if(选择器==null)
抛出错误.ArgumentNull(nameof(selector));
返回可枚举的。SelectManyIterator(源,选择器);
}
私有静态IEnumerable SelectManyIterator(
IEnumerable来源,
Func选择器)
{
foreach(源中的TSource source1)
{
foreach(TResult result in selector(source1))//错误在这里抛出
收益结果;
}
}

注意注释行。
选择器(source1)
将为第二个
NestedA
项返回null,此行将尝试获取null项的枚举数(
foreach
)。这就是为什么会出现错误。

要补充现有答案:


编译优化和运行时优化可能会导致报告行号不准确。不仅要检查可枚举项,还要检查foreach主体是否存在可能的未引用空值,特别是在对(静态声明的)数组进行迭代时。要补充现有答案,请执行以下操作:


编译优化和运行时优化可能会导致报告行号不准确。不仅要检查可枚举项,还要检查foreach主体是否存在可能的未引用空值,特别是在对(静态声明的)数组进行迭代时。这是否回答了您的问题@SirRufo不,我知道NullReferenceException是什么,但是我不知道为什么会发生这种情况。阅读该链接的答案,你就会知道如何修复它。这是否回答了你的问题@SirRufo不,我知道什么是NullReferenceException,但是我不知道为什么会发生这种情况。阅读该链接中的答案,你就会知道如何修复它。我认为SelectMany会首先使用两个项,然后在最后一个位置添加一个null(合并两个集合),这样它就会被``if(item!=null)``捕获,并不是说它会尝试迭代null。@MPal:No,
SelectMany
在展平之前从未将“null引用”转换为“具有默认值的单个元素的集合”。我可以理解它可能会自动将空引用视为一个空集合,但是
using System;
using System.Collections.Generic;
using System.Linq;

public class NestedB
{
    public string Test {get;set;}
}

public class NestedA
{
    public List<NestedB> NestedCollection {get;set;}
}

public class Program
{
    public static void Main()
    {
        var listOfA = new List<NestedA>
        {
            new NestedA
            {
                NestedCollection = new List<NestedB> 
                {
                    new NestedB {Test = "test"},
                    new NestedB {Test = "test"}
                }
            },
            new NestedA ()
        };
        
        var listOfB = listOfA.SelectMany(x => x.NestedCollection);
        
        foreach (var item in listOfB)
        {
            if (item != null)
            {
                Console.WriteLine(item.Test);
            }
        }
    }
    
}
Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Linq.Enumerable.SelectManySingleSelectorIterator`2.MoveNext()
   at Program.Main()
Command terminated by signal 6