在foreach中使用Null合并运算符和select表达式

时间:2016-02-08 18:29:12

标签: c# linq null null-coalescing-operator

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

}

相关歌曲可能是也可能不是null,有没有办法在这里使用空合并运算符?我仍然收到错误消息:

  

值不能为空

3 个答案:

答案 0 :(得分:4)

如果RelatedSongs为null,则在其上调用Select将抛出NullReferenceException,因为在解析左侧之后仅对计算空合并运算符。而且由于解决左侧会导致异常,因此它不会给您带来任何好处。

如果您正在使用C#6.0,则可以使用Null Propagation运算符 - ?. - 仅在RelatedSongs不为空时调用Select,并使用Null Coalescing运算符否则:

// 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>())
{
}

如果您使用的是C#5或更早版本,则必须手动检查空值:

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

答案 1 :(得分:1)

喜欢这个?

[编辑:删除简化]

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

它评估为单个Enumerable而不是两个。

答案 2 :(得分:0)

我认为@ juharr的评论很好 - 如果在循环之前执行空检查,它可能更具可读性。但是,如果你真的想使用空合并运算符,那么这将起到作用:

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

}

在尝试迭代RelatedSongs之前,您必须执行空检查。在您的问题中的示例中,您在尝试迭代后执行此操作,因此异常。