Why does the C# compiler remove a chain of method calls when the last one is conditional?

It comes down to the phrase:

(including evaluation of the receiver and parameters of the call) is omitted.

In the expression:

a.GetB().Hello();

the “evaluation of the receiver” is: a.GetB(). So: that is omitted as per the specification, and is a useful trick allowing [Conditional] to avoid overhead for things that aren’t used. When you put it into a local:

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

then the “evaluation of the receiver” is just the local b, but the original var b = a.GetB(); is still evaluated (even if the local b ends up getting removed).

This can have unintended consequences, so: use [Conditional] with great care. But the reasons are so that things like logging and debugging can be trivially added and removed. Note that parameters can also be problematic if treated naively:

LogStatus("added: " + engine.DoImportantStuff());

and:

var count = engine.DoImportantStuff();
LogStatus("added: " + count);

can be very different if LogStatus is marked [Conditional] – with the result that your actual “important stuff” didn’t get done.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)