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

?. operator in C# not compiling for unknown reason


In the following code, one of the two variants does not compile:

class C
{
    public decimal DecimalField;
}

static C GetC() { return new C(); } //Can return null in reality.

C c = GetC(); //Get a C value from somewhere, this might be null

string toString1 = c?.DecimalField?.ToString(); //Does not compile.
string toString2 = (c?.DecimalField)?.ToString(); //Compiles.

Error CS0023: Operator '?' cannot be applied to operand of type 'decimal'

Why does the simple form not compile?

Wouldn't the expression c?.DecimalField be of type decimal?? That value can be null so the ?. operator should apply. I'm quite sure this is so because in this code:

var decimalValue = c?.DecimalField;

the var does resolve to decimal? according to the IDE.


Solution

  • This is because the null-conditional access operator is "short-circuiting". That is, if you write a?.b.c and execute it with a being null, then not only is .b not executed, but .c is also not executed.

    As a consequence, when you write a?.b?.c, then the second null-conditional access operator is not about checking whether a or a.b is null. It's only about checking whether a.b is null. So, if a.b can never be null, like in your case, it doesn't make sense to use the null-conditional access operator, which is why the language does not allow it.

    This also explains why a?.b?.c and (a?.b)?.c are not the same thing.

    For more information about this, you can read the C# Language Design Meeting notes where this was decided.