Why Does .Net Foreach Loop Throw Nullrefexception When Collection Is Null

Why does .NET foreach loop throw NullRefException when collection is null?

Well, the short answer is "because that's the way the compiler designers designed it." Realistically, though, your collection object is null, so there's no way for the compiler to get the enumerator to loop through the collection.

If you really need to do something like this, try the null coalescing operator:

int[] array = null;

foreach (int i in array ?? Enumerable.Empty<int>())
{
System.Console.WriteLine(string.Format("{0}", i));
}

Why does foreach throw an exception if collection is null

IMO, throwing an exception in this scenario is a good thing. Otherwise, you risk forgetting to initialize your IEnumerable and running your code as though everything is fine (when in fact it's not iterating over your list like you want). In most programs, this mistake would quickly become obvious, but better to have your program crash than to risk it silently malfunctioning.

For example, pretend the following code regulates the nuclear power plant three miles down the road from where you live:

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

Now consider if there was a bug in getOverheatingCores() that caused it to occasionally return null. Under my preference of throwing an exception on the foreach, you'll very likely discover that during software development. Under your preference of silently treating null like an empty list, you'll discover that when there's a nuclear meltdown. Don't know about you, but I know which one I like better :)

How to avoid null checking before foreach IList

Well, you can try ?? operator:

testList ?? Enumerable.Empty<object>()

we get either testList itself or an empty IEnumerable<object>:

IList<object> testList = null;

...

// Or ?? new object[0] - whatever empty collection implementing IEnumerable<object>
foreach (var item in testList ?? Enumerable.Empty<object>())
{
//Do stuff.
}

foreach iterator null when looping through collection

The problem is not with i itself, most probably the incoming instance is null, you can use ?. operator in this case:

i?.incoming?.connection

Why does this foreach loop NOT throw the collection was modified exception?

I think this is because when the OrderBy starts executing it creates a copy of the list in the Buffer<T> class by calling ToArray, therefore modifying the original list doesn't throw an exception. Here is a reference to the source code

 internal Buffer(IEnumerable<TElement> source)
{
if (source is IIListProvider<TElement> iterator)
{
TElement[] array = iterator.ToArray();
_items = array;
_count = array.Length;
}
else
{
_items = EnumerableHelpers.ToArray(source, out _count);
}
}

Buffer is initialized in the GetEnumerator method:

public IEnumerator<TElement> GetEnumerator()
{
Buffer<TElement> buffer = new Buffer<TElement>(_source);
if (buffer._count > 0)
{
int[] map = SortedMap(buffer);
for (int i = 0; i < buffer._count; i++)
{
yield return buffer._items[map[i]];
}
}
}

Is if(items != null) superfluous before foreach(T item in items)?

You still need to check if (items != null) otherwise you will get NullReferenceException. However you can do something like this:

List<string> items = null;  
foreach (var item in items ?? new List<string>())
{
item.Dump();
}

but you might check performance of it. So I still prefer having if (items != null) first.

Based on Eric's Lippert suggestion I changed code to:

List<string> items = null;  
foreach (var item in items ?? Enumerable.Empty<string>())
{
item.Dump();
}


Related Topics



Leave a reply



Submit