Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 451
Danny Lager Avatar asked Aug 21 '17 12:08

Danny Lager


People also ask

Which operator is used with null operator?

The ?? operator is used to check null values and you can also assign a default value to a variable whose value is null(or nullable type).

What is null conditional operator in C#?

Null-conditional operators ?. and ?[] Available in C# 6 and later, a null-conditional operator applies a member access, ?. , or element access, ?[] , operation to its operand only if that operand evaluates to non-null; otherwise, it returns null . That is, If a evaluates to null , the result of a?. x or a?[x] is null .

What is null conditional and null-coalescing in C#?

it is used to define a default value for nullable value types or reference types. It returns the left-hand operand if the operand is not null; otherwise, it returns the right operand. In cases where a statement could return null, the null-coalescing operator can be used to ensure a reasonable value gets returned.

What is a conditional null?

The null conditional is a form of a member access operator (the .). Here's a simplified explanation for the null conditional operator: The expression A?. B evaluates to B if the left operand (A) is non-null; otherwise, it evaluates to null.


2 Answers

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?

like image 104
mjwills Avatar answered Sep 29 '22 03:09

mjwills


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
}
like image 20
Fruchtzwerg Avatar answered Sep 25 '22 03:09

Fruchtzwerg