20

I've been playing with C# 6's Null Conditional Operator (more info here).

I really like the syntax and I think it makes the code much more readable however I think it is questionable as to what exactly the code is going to do when you come across checking the value of a property on an object which itself might be null.

For example, if I had a class with a decimal property on it and I wanted a conditional check on the value of that decimal, I would write something like:

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

On the surface this looks great... If foo is not null, get the value of Bar and check if it's greater than a maximum value, if it is, do something.

However, what if foo is null?!

This documentation about the new and improved features of C# 6 says something along these lines:

if in fact the value of the object is null, the null-conditional operator will return null. It short-circuits the call to Bar, and immediately returns null, avoiding the programming error that would otherwise result in a NullReferenceException.

I've written a fiddle here which shows that it does indeed work and is doing what I'm expecting it to do however I can't get my head around how it is deciding the result of the condition.

How does the short-circuit equal a false? In my head this code is now going to say "If foo is null, check if null is > max, which is impossible, so return false" or "If foo is null, then foo != null will return false, so you get a false" however the documentation says the null conditional check returns null, not false.

4

3 回答 3

17

短路如何等于假?

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

大致相当于

Decimal? bar = null;
if (foo != null)
    bar = foo.Bar;

if (bar > max)
{
   // do something
}

因此,短路不等于false。它等于 a Decimal?(nullable Decimal),然后将其与 进行比较max

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

于 2017-08-21T12:12:39.883 回答
7

它使对 Bar 的调用短路

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

使用 null 条件运算符会返回一个可为空的值,例如double?. 然后将该值与 进行比较maxMicrosoft很好地描述了在这种比较中 null 的行为:

当您对可空类型执行比较时,如果其中一个可空类型的值为 null 而另一个不是,则所有比较的结果都为 false,但 !=(不等于)除外。

这表示:

if (null > max)
{
    //never called
}
于 2017-08-21T12:16:30.353 回答
-1

应该只用于关于对象属性的多个分配的Null Conditional Operator场景(请参阅对象映射等),如果每次出现属性的空条件,它可能会很无聊。

或者也适用于以下场景:

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

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

于 2017-08-21T13:22:22.053 回答