问题
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.
回答1:
How does the short-circuit equal a false?
if (foo?.Bar > max)
{
// do something
}
is roughly equivalent to:
Decimal? bar = null;
if (foo != null)
bar = foo.Bar;
if (bar > max)
{
// do something
}
Thus, the short circuit doesn't equal false
. It equals a Decimal?
(nullable Decimal
) which is then compared to max
.
See also: How does comparison operator works with null int?
回答2:
It short-circuits the call to Bar
means stop checking the following steps (.
) within an object reference chain if the parent is already null. This means operators like a comparison are not affected because you are using the value instead of moving in the chain. This behaviour is called null propagation. You can find some nice descriptions at Code Project or Dave Fancher.
Using the null conditional operator returns a nullable value like double?
. This value is then compared with max
. The behaviour of a null in such a comparision is well described by Microsoft:
When you perform comparisons with nullable types, if the value of one of the nullable types is null and the other is not, all comparisons evaluate to false except for != (not equal).
This means:
if (null > max)
{
//never called
}
回答3:
The Null Conditional Operator
should be used only for scenarios regarding objects properties's multiple assignments (see objects mapping, etc..) where it could be boring verify every time if occurs the null condition of the property.
Or also for scenarios like the following :
int? count = customers?[0]?.Orders?.Count(); // null if customers, the first customer, or Orders is null
Using this operator into an if
test expression it could lead to unexpected behaviours, for example in your if statements case on fiddler you get a "passed" test (the last if
statement) but with a null
value, which is obviously not a valid case
来源:https://stackoverflow.com/questions/45796633/using-the-null-conditional-operator-to-check-values-on-objects-which-might-be-nu