Note that:
var a1 = b?.c.d;
is entirely different from:
var a2 = (b?.c).d;
It is not very easy to explain in short how the unary operator ?.
works (yes, unary!). But the idea is that the rest of the "chain" of "operations" is skipped if the expression before ?.
is null.
So for a1
, you get a null of the compile-time type carried by member d
(or Nullable<>
of that type if necessary) whenever b
happens to be null. When b
happens to be non-null, you get the same as b.c.d
which may fail if b.c
is null.
But a2
is quite different. It will always blow up if b
is null, because then the parenthesis (b?.c)
will be a null reference, and the next .
operator will lead to NullReferenceException
. (I am assuming here that c
has a reference-type at compile-time.)
So do not think there is a kind of "left-associativity" that makes b?.c.d
equivalent to (b?.c).d
!
You can find a link to the preliminary C# Language Specification in this answer in another thread; they mention Null-conditional operator as an unary operator in § 7.7.1.