I did some digging and found the C# 5.0 language specification did actually already contain your second quote in section 17.4.2 The Conditional attribute on page 424.

Marc Gravell’s answer already shows that this behaviour is intended and what it means in practice. You also asked about the rationale behind this but seem to be dissatisfied by Marc's mention of removing overhead.

Maybe you wonder why it is considered overhead that can be removed?

a.GetB().Hello(); not being called at all in your scenario with Hello() being omitted might seem odd at face value.

I do not know the rationale behind the decision but I found some plausible reasoning my own. Maybe it can help you as well.

Method chaining is only possible if each previous method has a return value. This makes sense when you want to do something with these values, i.e. a.GetFoos().MakeBars().AnnounceBars();

If you have a function that only does something without returning a value you cannot chain something behind it but can put it at the end of the method chain, as is the case with your conditional method since it has to have the return type void.

Also note that the result of the previous method calls gets thrown away, so in your example of a.GetB().Hello(); your the result from GetB() has no reason to live after this statement is executed. Basically, you imply you need the result of GetB() only to use Hello() .

If Hello() is omitted why do you need to GetB() then? If you omit Hello() your line boils down to a.GetB(); without any assignment and many tools will give a warning that you are not using the return value because this is seldomly something you want to do.

The reason why you seem to not be okay with this is your method is not only trying to do what is necessary to return a certain value, but you also have a side effect, namely I/O. If you did instead have a pure function there would really be no reason to GetB() if you omit the subsequent call, i.e. if you are not going to do anything with the result.

If you assign the result of GetB() to a variable, this is a statement on it's own and will be executed anyway. So this reasoning explains why in

var b = a.GetB(); b.Hello();

only the call to Hello() is omitted while when using method chaining the whole chain is omitted.

You can also look somewhere entirely different to get a better perspective: the null-conditional operator or elvis operator ? introduced in C# 6.0. Although it only is syntactic sugar for a more complex expression with null checks it allows you to build something like a method chain with the option to short-circuit based on the null check.

E.g. GetFoos()?.MakeBars()?.AnnounceBars(); will only reach it’s end if the previous methods do not return null , otherwise subsequent calls are omitted.

It might be counter-intuitive but try thinking of your scenario as the inverse of this: the compiler omits your calls prior to Hello() in your a.GetB().Hello(); chain since you are not reaching the end of the chain anyway.

Disclaimer

This has all been armchair reasoning so please take this and the analogy with the elvis operator with a grain of salt.