boot4life
boot4life

Reputation: 5314

What is meant by "the null conditional operator short circuits"?

Note to future visitors: This question was based on faulty repro code. The ?. operator does indeed short circuit. You can close this browser tab now.


There are many sources on the web that claim that the null conditional operator (?.) short circuits (e.g. http://www.informit.com/articles/article.aspx?p=2421572, search for "circuit"). I cannot detect any such thing:

    static void Main()
    {
        var c = new C();

        Console.WriteLine(c?.Inner?.Inner); //does not rely on short circuiting, works
        Console.WriteLine(c?.Inner.Inner); //throws NullReferenceException
    }

    class C
    {
        public C Inner;
    }

Here, the first line works because of the second ?.. The second ?. saw null as its first operand and therefore returned null as well. This is not short circuiting.

Apparently, the rest of the chain executes even if the null case was triggered. The chain is not aborted. To me, short circuiting means that the chain is aborted. MSDN claims this is the case but the code example does not demonstrate short circuiting:

//The last example demonstrates that the null-condition operators are short-circuiting
int? count = customers?[0]?.Orders?.Count();
// null if customers, the first customer, or Orders is null

Was this behavior ever changed during the C# 6 development cycle? That would explain the bad sources on the web. And why is there so much talk about short circuiting if it's not there? I might be misunderstanding something here.

This is not a duplicate because it's about whether the operator short circuits or not (answer: no, although the accepted answer does not say that). This candidate is about nullable booleans and otherwise unrelated.

Upvotes: 0

Views: 2439

Answers (3)

Matthew Watson
Matthew Watson

Reputation: 109567

It does short-circuit (if by that we mean "terminate the chain of calls").

Consider this code:

using System;

namespace ConsoleApplication1
{
    class C
    {
        public C Inner
        {
            get
            {
                Console.WriteLine("Inner called.");
                return this; // Change this to `return null;`
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var c = new C();

            var x = c?.Inner?.Inner?.Inner;
        }
    }
}

Run that and it will print

Inner called.
Inner called.
Inner called.

Now change return this; to return null;, and it will print

Inner called.

thus demonstrating that the call chain was stopped at the first null.

Now change the expression to:

var x = c?.Inner?.Inner.Inner;

and it will only print one:

Inner called.

because it is being short circuited.

Obviously it has to access Inner at least once to see if it is null. If c itself is null, then Inner isn't accessed at all.

Note that short-circuiting does not mean a single ?. will always avoid null reference exception anywhere in the chain. Given the expression:

var x = c?.Inner.Inner;

it will give a null reference exception at the first use of .Inner because it has already checked that c is not null using c? but now it goes on to use .Inner.

If c was null, it would not have proceeded to access .Inner at all because of the c?..

Upvotes: 8

Scott Hannen
Scott Hannen

Reputation: 29212

In real simple terms, short-circuiting is a guarantee that if it determines that one property is null, it's not going to keep trying to evaluate the rest.

It might be clearer with an example that doesn't involve the null operator.

In the example below, we're checking to see if x is null before checking the value of its property.

if(x != null & x.SomeProperty == 1)

But this is still going to throw an exception if x is null because it's going to evaluate both conditions. Even if x is null it's still going to try to check x.SomeProperty and it's going to throw a NullReferenceException.

But if we use the && operator instead

if(x != null && x.SomeProperty == 1)

Then it "short circuits." If the first condition isn't true then it won't even evaluate the second condition. It's checking to see if they are both true. But if the first one isn't true then there's no way they can both be true - the value of the second one doesn't matter. So it stops after the first condition.

Short circuiting eventually means that if it evaluates anything that renders the remaining conditions irrelevant then it is guaranteed not to evaluate the remaining conditions.

Upvotes: 0

i3arnon
i3arnon

Reputation: 116548

Short circuit here means that when you have for example obj?.Property1?.Property2?.Property3 and obj is null then the whole expression returns null and no other properties are called (as they will throw).

That short circuiting can happen on each ?. depending on which part is null. if obj isn't null and the first Property is then only the other 2 won't be called. Same for the second and so forth.

The thing being short circuited is the expression, not the rest of the statements after that expression.

Upvotes: 4

Related Questions