C#空传播运算符/条件访问表达式&if块

c#-6.0中的Null传播运算符/条件访问表达式看起来非常方便。 但我很好奇它是否有助于解决检查子成员是否为null然后在if块内的所述子成员上调用布尔方法的问题:

public class Container{ IEnumerable Objects {get;set;} } public Container BuildContainer() { var c = new Container(); if (/* Some Random Condition */) c.Objects = new List{1,2,4}; } public void Test() { var c = BuildContainer(); //Old way if ( null != c && null != c.Objects && c.Objects.Any()) Console.Write("Container has items!"); //C# 6 way? if (c?.Object?.Any()) Console.Write("Container has items!"); } 

请问c?.Object?.Any()编译? 如果传播运算符短路(我认为这是正确的术语)为null,那么你有if (null) ,这是无效的。

C#团队是否会解决这个问题,或者我是否错过了null传播运算符的预期用例?

它不会这样工作。 您可以跳过说明并查看下面的代码:)

如你所知?. 如果子成员为null,则运算符将返回null。 但是如果我们试图获得一个不可为空的成员,比如返回boolAny()方法,会发生什么? 答案是编译器将“包装” Nullable<>的返回值。 例如, Object?.Any()会给我们bool? (这是Nullable ),而不是bool

唯一不允许我们在if语句中使用这个表达式的是它不能隐式地转换为bool 。 但是你可以明确地进行比较,我更喜欢这样比较true

 if (c?.Object?.Any() == true) Console.Write("Container has items!"); 

感谢@DaveSexton还有另一种方式:

 if (c?.Object?.Any() ?? false) Console.Write("Container has items!"); 

但就我而言,与true比较似乎更自然:)

空条件运算符将返回null或表达式结尾处的值。 对于值类型它将返回Nullable ,因此在您的情况下,它将是Nullabe 。 如果我们查看C#中即将发布的function文档中的示例( 此处指定) ,它有一个示例:

 int? first = customers?[0].Orders.Count(); 

在上面的示例中,将返回Nullable而不是int 。 对于bool ,它将返回Nullable

如果您在Visual Studio“14”CTP中尝试以下代码:

 Nullable ifExist = c?.Objects?.Any(); 

上面一行的结果是Nullable / bool? 。 之后您可以进行比较,例如:

使用null合并运算符??

  if (c?.Object?.Any() ?? false) 

使用Nullable.GetValueOrDefault方法

 if ((c?.Objects?.Any()).GetValueOrDefault()) 

使用与true比较

 if (c?.Objects?.Any() == true)