Martin Mazza Dawson February 2016

C# Using Null coalescing operator in foreach with select expression

foreach (var item in Model.PublishedSong.RelatedSongs.Select((value, i) => new { value, i }) ?? Enumerable.Empty <dynamic>())
{

}

Related Songs may or may not be null, is there any way to use null coalescing operator here? I still get the error message:

value cannot be null

Answers


Meirion Hughes February 2016

Like this?

[Edit: Removed simplification]

Model.PublishedSong
   .SelectMany(x=>
      (x.RelatedSongs??Enumerable.Empty<Song>())
         .Select((x,i) => new {Value = x, Index = i));

It evaluates to a single Enumerable rather than two.


Avner Shahar-Kashtan February 2016

If RelatedSongs is null, calling Select on it will throw a NullReferenceException, because the null coalescing operator is evaluated only after the left-hand side is resolved. And since resolving the left hand side results in an exception, it won't do you any good.

If you're using C# 6.0, you can use the Null Propagation operator - ?. - to call Select only if RelatedSongs isn't null, and use the Null Coalescing operator otherwise:

// This will return null if Relatedsongs is null, or call Select otherwise.
foreach (var item in Model.PublishedSong.RelatedSongs?.Select((value, i) => new { value, i })  
                             ?? Enumerable.Empty <dynamic>())
{
}

If you're using C# 5 or earlier, you'll have to check for null manually:

foreach (var item in Model.PublishedSong.RelatedSongs != null 
                             ? Model.PublishedSong.RelatedSongs.Select((value, i) => new { value, i }) 
                             : Enumerable.Empty <dynamic>())
{
}


Jason Boyd February 2016

I think @juharr's comment is good - it may be more readable if you perform the null check before the loop. However, if you really want to use the null coalescing operator this will do the trick:

foreach (var item in (Model.PublishedSong.RelatedSongs ?? Enumerable.Empty<TypeOfRelatedSong>()).Select((value, i) => new { value, i }))
{

}

You have to perform the null check before attempting to iterate over RelatedSongs. In the example in your question you are doing it after attempting to iterate, hence the exception.

Post Status

Asked in February 2016
Viewed 3,035 times
Voted 8
Answered 3 times

Search




Leave an answer