Mentre rispondendo ad una domanda su SO ieri, ho notato che se un oggetto viene inizializzato tramite un inizializzazione degli oggetti, il compilatore crea una variabile in più locale.Quando si utilizzano gli inizializzatori di oggetti, perché il compilatore genera una variabile locale extra?
Si consideri il codice C# 3.0 in seguito, compilato in modalità di rilascio in 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);
}
}
Utilizzando riflettore, siamo in grado di esaminare il codice per il metodo principale:
.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
}
Qui, possiamo vedere che il compilatore ha generato due riferimenti a un'istanza di Class2
(class2
e <>g__initLocal0
), ma solo riferimento a un'istanza di Class1
(class1
).
Ora, non ho molta familiarità con IL, ma sembra che stia creando un'istanza <>g__initLocal0
, prima di impostare class2 = <>g__initLocal0
.
Perché succede?
ne consegue quindi, che c'è un sovraccarico di prestazioni quando si utilizzano Inizializzatori oggetti (anche se è molto piccola)?
+1, ottimo esempio – Tenner