使用Null条件运算符检查可能为null的对象的值

我一直在玩C#6的Null Conditional Operator( 更多信息在这里 )。

我非常喜欢语法,我认为它使代码更具可读性,但我认为当你遇到一个本身可能为null的对象上的属性值时,代码究竟要做什么是值得怀疑的。

例如,如果我有一个带有十进制属性的类,并且我想要对该十进制值进行条件检查,我会写如下:

if (foo?.Bar > max) { // do something } 

从表面上看,这看起来很棒……如果foo不为null,则获取Bar的值并检查它是否大于最大值,如果是,则执行某些操作。

但是,如果foo为null会怎么样?!

有关C#6的新function和改进function的文档说明了以下内容:

如果实际上对象的值为null,则null条件运算符将返回null。 它将对Bar的调用短路,并立即返回null,避免编程错误,否则会导致NullReferenceException。

我在这里写了一个小提琴,它表明它确实有效,并且正在做我期待它做的事情但是我无法理解它是如何决定条件的结果的。

短路如何等于假 ? 在我的脑海中,这段代码现在要说“如果foo为null,检查null是否> max,这是不可能的,所以返回false”或“如果foo为null,那么foo!= null将返回false,所以你得到一个假“但文档说null条件检查返回null,而不是false。

短路如何等于假?

 if (foo?.Bar > max) { // do something } 

大致相当于 :

 Decimal? bar = null; if (foo != null) bar = foo.Bar; if (bar > max) { // do something } 

因此,短路不等于false 。 它等于Decimal? (可空的Decimal然后max 进行比较。

另请参见: 比较运算符如何与null int一起使用?

它将对Bar的调用短路

表示如果父项已经为空,则停止检查对象引用链中的以下步骤( . )。 这意味着比较运算符不会受到影响,因为您使用的是值而不是在链移动 。 此行为称为空传播。 你可以在Code Project或Dave Fancher找到一些不错的描述。

使用null条件运算符返回像double?这样的可空值double? 。 然后将该值与max进行比较。 微软很好地描述了这种比较中null的行为:

当您使用可空类型进行比较时,如果其中一个可空类型的值为null而另一个不为null,则除了!=(不等于)之外,所有比较都会计算为false。

这意味着:

 if (null > max) { //never called } 

Null Conditional Operator应仅用于有关对象属性的多个赋值的场景(请参阅对象映射等),如果出现属性的null条件,则每次都可能无聊validation。

或者对于以下情况:

 int? count = customers?[0]?.Orders?.Count(); // null if customers, the first customer, or Orders is null 

将此运算符用于if测试表达式可能会导致意外行为,例如在fiddler的if语句中,您获得“传递”测试(最后一个if语句)但是具有null值,这显然不是有效的情况