C#Null与LINQ合并

我有2个类,看起来像这样:

class Widget { string Selected { get; set; } List Options { get; set; } } class Option { string InternalCode { get; set; } string ExternalCode { get; set; } } 

使用每个客户端的不同数据动态填充Options ,以显示ExternalCode作为选项

Selected使用ExternalCode填充。

然后我需要访问匹配的InternalCode

目前我这样做:

 var option = widget.Options.SingleOrDefault(o => o.ExternalCode == widget.Selected); var internalCode = option == null ? string.Empty : option.InternalCode; 

这是否可以使用Null Coalesce使用单行?

是的,您可以使用null传播和null合并运算符,如果您可以使用C#6,它适合您的需要:

 var option = widget.Options .SingleOrDefault(o => o.ExternalCode == widget.Selected)?.InternalCode ?? string.Empty; 

?. 将转换为您使用option == null ? 部分。

当然,只有一个小小的变化:

 var option = widget.Options .Where(o => o.ExternalCode == widget.Selected) .Select(o => o.InternalCode) .FirstOrDefault() ?? ""; 

换句话说,将匹配选项的序列投影到一系列内部代码,然后取第一个,默认为null …这允许您对结果使用null-coalescing运算符。

您可以根据Patrick的答案使用空条件运算符,但我个人更喜欢这个答案中的代码 – 我认为它更容易理解。

如果你编写了扩展方法,你可以这样做:

 public static class MonadExtensions { public static TResult With(TSource source, Func action) where TSource : class { if (source != default(TSource)) return action(source); return default(TResult); } } 

并使用它:

 var internalCode = widget.Options.SingleOrDefault(o => o.ExternalCode == widget.Selected).With(o=>o.InternalCode)??""; 

这是否可以使用Null Coalesce使用单行?

是的,这是如何:

 var option = (widget.Options.SingleOrDefault(o => o.ExternalCode == widget.Selected) ?? new Option() { InternalCode = string.Empty }).InternalCode; 

到目前为止,使用单个语句的其他答案会产生错误的结果,如果匹配的Option实例与InternalCode == null