Null propagation operator and foreach

Reading a lot about the Null propagation operator ?. , I found no answer whether it is helpful in the following scenario.

Code that throws:

int[] values = null;

foreach ( var i in values ) // Throws since values is null.
{
    // ...
}

To make this working, I have to add a null check before access to the values variable.

Most likely the above code is out of scope of the design considerations for the Null propagation operator. Still, to be sure, I have to ask.

My question:

Is the Null propagation operator helpful when trying to access null collections in a foreach loop?


No it is not. It's designed to allow access members of an object in a secure way. In this case you have to check whether the array is null.


I've found another, working way:

When using Jon Skeet's (et al) fantastic MoreLinq extensions, there is a ForEach extension method which I can use in my initial example like:

int[] values = null;

values?.ForEach(i=> /*...*/); // Does not throw, even values is null.

How would you porpose to use it?

The code you provided:

int[] values = null;

foreach (var i in values)
{
    // ...
}

enxpands into something:

int[] values = null;

var enumerator = values.GetEnumerator();
try
{
    while (enumerator.MoveNext())
    {
        var i = enumerator.Current;
        // ...
    }
}
finally
{
    var disposable = enumerator as IDisposable;
    if (disposable != null)
    {
        disposable.Dispose();
    }
}

I guess you could write something like this:

int[] values = null;

foreach (var i in values?.)
{
    // ...
}

The compiler would have to expand it to something like this:

int[] values = null;

var enumerator = values?.GetEnumerator();
try
{
    while (enumerator?.MoveNext() ?? false)
    {
        var i = enumerator.Current;
        // ...
    }
}
finally
{
    var disposable = enumerator as IDisposable;
    if (disposable != null)
    {
        disposable.Dispose();
    }
}

And have in mind that:

a = b?.M();

expands into:

a = b == null ? null : b.M();

If you want to not explicitly write the if statement, you can always rely on the good old null-coalescing operator (??):

int[] values = null;

foreach (var i in values ?? Enumerable.Empty<int>())
{
    // ...
}
链接地址: http://www.djcxy.com/p/13058.html

上一篇: Monadic在C#6.0中空检查

下一篇: 空传播操作符和foreach