Say I have a struct
public struct Foo
{
...
}
Is there any difference between
Foo foo = new Foo();
and <
For value-types, the options are, practically speaking, equivalent.
However, I was intrigued by Jon Skeet's empirical research into which 'instructions' result in the invocation of a struct's parameterless default constructor when it is specified in CIL (you can't do it in C# because it doesn't let you). Amongst other things, he'd tried out default(T)
and new T()
where T
is a type parameter. They appeared equivalent; neither of them appeared to call the constructor.
But the one case (it appears) he hadn't tried was default(Foo)
where Foo
is an actual
struct type.
So I took his code for the 'hacked' struct and tried that out for myself.
It turns out that default(Foo) doesn't call the constructor, whereas new Foo() in fact does.
Using a struct type Oddity
that specifies a parameterless constructor:
With optimizations turned off, the method:
private void CallDefault()
{
Oddity a = default(Oddity);
}
produces the CIL (without nop
s, ret
s etc.):
L_0001: ldloca.s a
L_0003: initobj [Oddity]Oddity
whereas the method:
private void CallNew()
{
Oddity b = new Oddity();
}
produces:
L_0001: ldloca.s b
L_0003: call instance void [Oddity]Oddity::.ctor()
With optimizations turned on, the compiler appears to optimize away pretty much all of the CallDefault
method into a no-op, but keeps the call to the constructor in CallNew
(for potential side-effects?).