Für den folgenden Code-Schnipsel:Warum Int32.ToString() Call-Anweisung statt Callvirt ausgeben?
struct Test
{
public override string ToString()
{
return "";
}
}
public class Program
{
public static void Main()
{
Test a = new Test();
a.ToString();
Int32 b = 5;
b.ToString();
}
}
Compiler die folgenden IL aussendet:
.locals init ([0] valuetype ConsoleApplication2.Test a,
[1] int32 b)
IL_0000: nop
IL_0001: ldloca.s a
IL_0003: initobj ConsoleApplication2.Test
IL_0009: ldloca.s a
IL_000b: constrained. ConsoleApplication2.Test
IL_0011: callvirt instance string [mscorlib]System.Object::ToString()
IL_0016: pop
IL_0017: ldc.i4.5
IL_0018: stloc.1
IL_0019: ldloca.s b
IL_001b: call instance string [mscorlib]System.Int32::ToString()
IL_0020: pop
IL_0021: ret
Da beide Typwert Test
und Int32
die ToString()
Methode überschreiben, ich glaube, kein Boxen in beide a.ToString()
auftreten und b.ToString()
. Daher frage ich mich, warum der Compiler constraned
+ callvirt
für Test
und call
für Int32
ausstrahlt?
Vielen Dank, ich denke auch, es ist die Compiler-Optimierung funktioniert. Aber ich kann kein Material finden, das meine Vermutung stützt. Ich würde es also schätzen, wenn Sie irgendwelche Dokumente über diese spezielle Optimierung für primitive Typen bereitstellen könnten. Danke noch einmal. –
@LifuHuang Meine Antwort aktualisiert. –
Danke @Eli Arbel, du hast meine Frage wirklich gelöst:) –