Search code examples
c#c#-6.0null-conditional-operator

Using the Null Conditional Operator to check values on objects which might be null


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.


Solution

  • 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?