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
How to Use Npm with ASP.NET Core
How Can Xml Documentation for Web API Include Documentation from Beyond the Main Project
Could Not Load File or Assembly 'System.Web.Http 4.0.0 After Update from 2012 to 2013
Should I Take Ilogger, Ilogger<T>, Iloggerfactory or Iloggerprovider for a Library
Entity Framework. Delete All Rows in Table
Send Email via C# Through Google Apps Account
Event Action<> VS Event Eventhandler<>
Custom Authentication in ASP.NET-Core
Using Razor Outside of MVC in .Net Core
Startup.Cs in a Self-Hosted .Net Core Console Application
How to Use a Client Certificate to Authenticate and Authorize in a Web API
Differencebetween Ienumerator and Ienumerable
If Strings Are Immutable in .Net, Then Why Does Substring Take O(N) Time
Visual Studio Displaying Errors Even If Projects Build
How to Optionally Turn Off the JSONignore Attribute at Runtime