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。 但是如果我们试图获得一个不可为空的成员,比如返回bool
的Any()
方法,会发生什么? 答案是编译器将“包装” 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
方法
if ((c?.Objects?.Any()).GetValueOrDefault())
使用与true
比较
if (c?.Objects?.Any() == true)