public struct Test
{
public double Val;
public Test(double val = double.NaN) { Val = val; }
public bool IsValid { get { return !double.IsNaN(Val); } }
}
Te
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.