Al responder a una pregunta sobre SO ayer, noté que si un objeto se inicializa con un Inicializador de objetos, el compilador crea una variable local adicional.Al utilizar inicializadores de objetos, ¿por qué el compilador genera una variable local adicional?
Consideremos el siguiente código de C# 3.0, compilado en modo de lanzamiento de VS2008:
public class Class1
{
public string Foo { get; set; }
}
public class Class2
{
public string Foo { get; set; }
}
public class TestHarness
{
static void Main(string[] args)
{
Class1 class1 = new Class1();
class1.Foo = "fooBar";
Class2 class2 =
new Class2
{
Foo = "fooBar2"
};
Console.WriteLine(class1.Foo);
Console.WriteLine(class2.Foo);
}
}
El uso del reflector, podemos examinar el código para el método principal:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
.maxstack 2
.locals init (
[0] class ClassLibrary1.Class1 class1,
[1] class ClassLibrary1.Class2 class2,
[2] class ClassLibrary1.Class2 <>g__initLocal0)
L_0000: newobj instance void ClassLibrary1.Class1::.ctor()
L_0005: stloc.0
L_0006: ldloc.0
L_0007: ldstr "fooBar"
L_000c: callvirt instance void ClassLibrary1.Class1::set_Foo(string)
L_0011: newobj instance void ClassLibrary1.Class2::.ctor()
L_0016: stloc.2
L_0017: ldloc.2
L_0018: ldstr "fooBar2"
L_001d: callvirt instance void ClassLibrary1.Class2::set_Foo(string)
L_0022: ldloc.2
L_0023: stloc.1
L_0024: ldloc.0
L_0025: callvirt instance string ClassLibrary1.Class1::get_Foo()
L_002a: call void [mscorlib]System.Console::WriteLine(string)
L_002f: ldloc.1
L_0030: callvirt instance string ClassLibrary1.Class2::get_Foo()
L_0035: call void [mscorlib]System.Console::WriteLine(string)
L_003a: ret
}
Aquí, podemos ver que el compilador ha generado dos referencias a una instancia de Class2
(class2
y <>g__initLocal0
), pero solo una referencia a una instancia de Class1
(class1
).
Ahora, no estoy muy familiarizado con IL, pero parece que está instanciando <>g__initLocal0
, antes de establecer class2 = <>g__initLocal0
.
¿Por qué sucede esto?
¿Sigue entonces, que hay una sobrecarga de rendimiento al usar Inicializadores de objetos (incluso si es muy leve)?
+1, gran ejemplo – Tenner