Ил показывает это: Первый звонок в штучной упаковке:
IL_0000: nop
IL_0001: ldc.i4.1
IL_0002: stloc.0 // a
IL_0003: ldc.i4.1
IL_0004: stloc.1 // b
IL_0005: ldloca.s 01 // b
IL_0007: ldloc.0 // a
IL_0008: box System.Int32
IL_000D: call System.Int16.Equals
IL_0012: call System.Console.WriteLine
IL_0017: nop
IL_0018: ret
Второе: не
IL_0000: nop
IL_0001: ldc.i4.1
IL_0002: stloc.0 // a
IL_0003: ldc.i4.1
IL_0004: stloc.1 // b
IL_0005: ldloca.s 00 // a
IL_0007: ldloc.1 // b
IL_0008: call System.Int32.Equals
IL_000D: call System.Console.WriteLine
IL_0012: nop
IL_0013: ret
Ил генерируется для универсального метода всегда бокс:
Test<T1,T2>:
IL_0000: nop
IL_0001: ldarga.s 02
IL_0003: ldarg.1
IL_0004: box T1
IL_0009: constrained. T2
IL_000F: callvirt System.Object.Equals
IL_0014: call System.Console.WriteLine
IL_0019: nop
IL_001A: ldarga.s 01
IL_001C: ldarg.2
IL_001D: box T2
IL_0022: constrained. T1
IL_0028: callvirt System.Object.Equals
IL_002D: call System.Console.WriteLine
IL_0032: nop
IL_0033: ret
и звонок по этому методу:
IL_0000: nop
IL_0001: ldc.i4.1
IL_0002: stloc.0 // a
IL_0003: ldc.i4.1
IL_0004: stloc.1 // b
IL_0005: ldarg.0
IL_0006: ldloc.0 // a
IL_0007: ldloc.1 // b
IL_0008: call Test<Int32,Int16>
IL_000D: nop
IL_000E: ret
поэтому, даже когда тип известен во время компиляции, значения по-прежнему будут вставлены в коробку.
Также смотрите: [Когда общий тип разрешен в C#?] (Http://stackoverflow.com/questions/17734247/when-is-the-generic-type-resolved-in-c) – Costas
и это [почему этот родовой не разрешен во время компиляции?] (http://stackoverflow.com/questions/6127855/why-is-this-generic-not-resolved-at-compile-time) – Costas
Глядя на IL, код в общем методе всегда помещается в коробку, а код в «основном» методе - нет. – Costas