Problem
As a result, I frequently find myself in this predicament… where Do. Something(…), for example, yields a null collection:
int[] returnArray = Do.Something(...);
Then I try to use this collection in the following way:
foreach (int i in returnArray)
{
// do some more stuff
}
Why can’t a foreach loop operate on a null collection, I’m just interested. With a null collection, I would expect 0 iterations to be executed… however, a NullReferenceException is thrown. Is there any reason for this?
This is inconvenient because I’m working with APIs that aren’t explicit about what they return, so I end up using if (someCollection!= null) all over the place…
Edit: Thanks to everyone who explained that foreach uses GetEnumerator, and if there isn’t an enumerator to get, foreach would fail. I suppose I’m wondering why the language/runtime can’t or won’t check for null before taking the enumerator. The behavior would still appear to be clearly defined, in my opinion.
Asked by Polaris878
Solution #1
“Because that’s how the compiler designers planned it,” is the short response. However, because your collection object is null, the compiler has no way of getting the enumerator to loop through the collection.
Try the null coalescing operator if you truly need to accomplish something like this:
int[] array = null;
foreach (int i in array ?? Enumerable.Empty<int>())
{
System.Console.WriteLine(string.Format("{0}", i));
}
Answered by Robaticus
Solution #2
The GetEnumerator function is called by a foreach loop. This method call throws a NullReferenceException if the collection is null.
Returning a null collection is bad practice; instead, your methods should return an empty collection.
Answered by SLaks
Solution #3
An empty collection and a null reference to a collection are not the same thing.
Internally, when you use foreach, you’re invoking the IEnumerable’s GetEnumerator() method. This exception is thrown when the reference is null.
An empty IEnumerable or IEnumerableT>, on the other hand, is totally legal. Foreach will not “iterate” over anything in this example (since the collection is empty), but it will not throw either, because this is a completely legal scenario.
Edit:
If you need to get around this, I recommend using an extension method:
public static IEnumerable<T> AsNotNull<T>(this IEnumerable<T> original)
{
return original ?? Enumerable.Empty<T>();
}
You can then just dial:
foreach (int i in returnArray.AsNotNull())
{
// do some more stuff
}
Answered by Reed Copsey
Solution #4
It was answered a long time ago, but I tried to implement it in the following way to avoid a null pointer exception and thought it might be useful for someone using the C# null check operator?
//fragments is a list which can be null
fragments?.ForEach((obj) =>
{
//do something with obj
});
Answered by Devesh
Solution #5
Another way to deal around this is to use an extension.
public static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
{
if(items == null) return;
foreach (var item in items) action(item);
}
Consume in a variety of ways:
(1) using a T-accepting method:
returnArray.ForEach(Console.WriteLine);
(2) using the following phrase:
returnArray.ForEach(i => UpdateStatus(string.Format("{0}% complete", i)));
(3) using an anonymous multiline technique
int toCompare = 10;
returnArray.ForEach(i =>
{
var thisInt = i;
var next = i++;
if(next > 10) Console.WriteLine("Match: {0}", i);
});
Answered by Jay
Post is based on https://stackoverflow.com/questions/3088147/why-does-net-foreach-loop-throw-nullrefexception-when-collection-is-null