Dlaczego podczas korzystania z inicjalizatorów obiektów kompilator generuje dodatkową zmienną lokalną?

Odpowiadając na pytanie dotyczące SO wczoraj, zauważyłem, że jeśli obiekt jest inicjowany za pomocą inicjatora obiektów, kompilator tworzy dodatkową zmienną lokalną.

Rozważmy następujący kod C # 3.0, skompilowany w trybie wydania w 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);
    }
}

Za pomocą reflektora możemy zbadać kod metody głównej:

.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 
}

Tutaj widzimy, że kompilator wygenerował dwa odwołania do instancjiClass2 (class2 i<>g__initLocal0), ale tylko jedno odniesienie do instancjiClass1 (class1).

Teraz nie jestem zbyt dobrze zaznajomiony z IL, ale wygląda na to, że tworzy instancję<>g__initLocal0, przed ustawieniemclass2 = <>g__initLocal0.

Dlaczego to się dzieje?

Czy zatem wynika z tego, że podczas korzystania z Inicjalizatorów obiektów jest narzut wydajności (nawet jeśli jest bardzo mały)?

questionAnswers(3)

yourAnswerToTheQuestion