public struct Test
{
public double Val;
public Test(double val = double.NaN) { Val = val; }
public bool IsValid { get { return !double.IsNaN(Val); } }
}
Test myTest = new Test();
bool valid = myTest.IsValid;
The above gives valid==true
because the constructor with default arg is NOT called and the object is created with the standard default val = 0.0.
If the struct is a class the behaviour is valid==false
which is what I would expect.
I find this difference in behaviour and particularly the behaviour in the struct case suprising and unintuitive - what is going on? What does the default arg on the stuct construct serve? If its useless why let this compile?
Update: To clarify the focus here is not on what the behaviour is - but rather why does this compile without warning and behave unintuitively. I.e If the default arg is not applied because in the new Test() case the constructor is not called then why let it compile?
In C# (at least until C# 6 - see blog post), invoking new Test()
is equivalent to writing default(Test)
- no constructor is actually called, the default value is provided.
The default arg serves no purpose, what happens is that it is likely the result of an oversight in the implementation of the compiler, due to the fact that optional arguments were only added in C# 4:
The code that translates what new Test()
means is probably unaware of the existence of optional arguments;
After digging into comments, I noticed the following gem by Mads Torgersen:
It is true that the compiler implementation has so far "optimized" 'new T()' to mean essentially default(T) when T is a struct. That was actually a bug - it was always supposed to call an actual parameterless constructor if there is one - which there could have been all along, since it is allowed in IL.
For your example, it means that new Test()
is effectively replaced by the compiler to default(Test)
- so that is a bug, which will be fixed in the next version of Visual Studio.
In other words, you have a corner case. That would probably be a good time to look at how that behaves in the next version of Visual Studio, as that behavior is changing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With