Back in 2015 I wrote an article about the C# default parameterless constructor and how it goes away if you write one with default values for the parameters.
I have since seen this behavior more and more and I actually spent more time understanding what was going on.
It turns out that my assumption was wrong (see the older article) and the explanation is actually simpler:
When a default value is set to a parameter, it is actually replaced at compile time where the calls don’t set the parameters.
So now the IL looks like you wrote the code by setting the default values where you call the empty construcors/methods.
We will take the following example:
Fairly straight forward example. Let’s look at the IL for the constructor:
What’s going on here? Well, the CLR is given a hint that the parameter
bar is optionnal with
And the default value is given on the following line:
.param  = int32(0x00000016) (0x00000016 is 22 in base 10)
As we can see, the compiler does not create a new parameterless constructor calling the other one with the default value.
The reason was explained by Eric Lippert over here (the 4 posts are definitely worth a read): https://blogs.msdn.microsoft.com/ericlippert/2011/05/16/optional-argument-corner-cases-part-three/
I already mentionned how it was kind of annoying with AutoMapper (in the previous article) and I actually have a case that I run into more often that is equally annoying.
Let’s say you have a class like this:
The IL for the GetNewItem method will look like this:
As you can see, the compiler is also using the
new T() wouldn’t be correct) in this case so the parameterless constructor is required.
(it wouldn’t let you compile if it wasn’t the case anyway since the constraint
new() forces you to have a parameterless public constructor).
I’ll write the next few articles about features I wish C# was handling differently.
See something wrong or want to ask a question? Get in touch on Twitter