I have encountered in my code similiar situation to the one presented in code below. The problem is that for some reason iterating in foreach loop throws NullReferenceException
.
My question is, why this happens?
If I create iterator that returns empty element myself, foreach
handles it, and simply prints
empty line.
Result of following code is: test, test, NullReferenceException.
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);
}
}
}
}
Stacktrace:
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
This is the problem:
listOfA.SelectMany(x => x.NestedCollection)
Your second NestedA
instance doesn't have a NestedCollection
, so it's trying to find "all the items in a null reference". You'd have exactly the same problem if you did this manually:
var nestedA = new NestedA();
// This will throw an exception, because nestedA.NestedCollectoin is null
foreach (var nestedB in nestedA.NestedCollection)
{
}
The simplest fix to this would be to make NestedCollection
a read-only property, but initialize it to start with:
public List<NestedB> NestedCollection { get; } = new List<NestedB>();
Then you'll need to modify the initialization of your first NestedA
to use a collection initializer:
new NestedA
{
NestedCollection =
{
new NestedB { Test = "test" },
new NestedB { Test = "test" }
}
}
If you don't want to do that, you could change the SelectMany
call instead:
var listOfB = listOfA.SelectMany(x => x.NestedCollection ?? Enumerable.Empty<NestedB>())
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With