Eine Werttyp lokale Variable (z. B. S s;
gegeben struct S{}
) wird durch den Aufruf seines Konstruktors initialisiert (z. B. a = new S(11)
), wenn S
einen Konstruktor mit int
Parameter deklariert. Dann new S(11)
kompiliert:Warum Werttyp-Felder instanziiert werden können, anstatt initialisiert?
ldloca.s V_0
ldc.i4.s 11
call instance void S::.ctor(int32)
Wenn jedoch s
ein Feld (z.B. class C { S s;
) ist, dann ist sie nicht in der gleichen Weise initialisiert. In Bezug auf die folgende Instanzmethode der Klasse C
: void setS(int n) { s = new S(n); }
es kompiliert:
ldarg.0
ldarg.1
newobj instance void S::.ctor(int32)
stfld valuetype S C::s
Ich habe erwartet, dass es mit dem folgenden Code kompilieren würde, die mehr in der Nähe des Fall einer lokalen Variablen ist:
ldarg.0
ldflda valuetype S C::s
ldarg.1
call instance void S::.ctor(int32)
Darüber hinaus, wenn ich klar verstehe, hat die newobj instance void S::.ctor(int32)
höhere Overhead und Belastungen GC. Hab ich recht?
Warum verwendet der C# -Compiler für Werttypfelder einen anderen Ansatz als für lokale Variablen?
Wie Jons korrekte Antwort feststellt, kann die Optimierung nicht durchgeführt werden, wenn die optimierte Version ein anderes beobachtbares Verhalten als die nicht optimierte Version hervorbringen könnte. Zur Erinnerung: Diese Optimierung wird als "copy elision" bezeichnet und ist in C++ - Compilern üblich. Wenn Sie mehr darüber erfahren möchten, kennen Sie jetzt einen Suchbegriff, den Sie verwenden können. –