2016-04-22 18 views
1

Ich stolperte über einen seltsamen IL-Code für die folgenden Proben emittieren:C# gibt Box/Unbox aus, wenn generische Typen zugewiesen werden?

class Sample 
{ 
    void Foo<T,U>(T t, U u) where U : T { t = u; } 
} 

Die IL für den Körper von Foo emittierten

IL_0001: ldarg.2  // u 
IL_0002: box   !!1/*U*/ 
IL_0007: unbox.any !!0/*T*/ 
IL_000c: starg.s  t 

Also meine Frage: Warum es ein Unboxing emittiert/Boxbetrieb? Ich würde mir vorstellen, dass die Konversation niemals boxen muss, da es entweder ein Referenztyp ist oder sowieso der gleiche Datentyp.

noch seltsame, auch wenn ich explizit die Typ-Parameter sagt, sind Referenztypen, die nicht den emittierten Code in irgendeiner Weise ändert:

class Sample 
{ 
    void Foo<T, U>(T t, U u) where U : class, T where T : class { t = u; } 
} 

(IL-Ausgang das gleiche ist)

So. . Warum?

+0

Mögliche Duplikat [Warum gibt der Compiler-Box Anweisungen Instanzen eines Referenztyps vergleichen?] (Http://stackoverflow.com/questions/4475576/why-the-compiler-emits-box-instructions- zu vergleichen-Instanzen eines Referenztyps) – Imi

Antwort

1

T könnte ein Referenztyp sein (Schnittstelle, object oder System.ValueType), während U eine Struktur ist, z.

Foo<IConvertible, int>(1, 2); 
Foo<object, int>("foo", 2); 
+0

OK, Sie haben Recht mit der ersten Probe. Was ist mit der zweiten Probe, die immer noch eine Boxkonversation ausstrahlt? Ich fordere ausdrücklich, dass T und U Referenztypen sind. – Imi

+2

@Imi - Siehe [diese Frage] (http://stackoverflow.com/questions/4475576/why-the-compiler-emits-box-instructions-to-compare-instances-of-a-reference-type) für warum Boxen ist erforderlich. – Lee