Let's examine the MSIL code generated for the following generic method:
public static U BoxValue<T, U>(T value)
where T : struct, U
where U : class
{
return value;
}
Look:
.method public hidebysig static !!U BoxValue<valuetype .ctor
([mscorlib]System.ValueType, !!U) T,class U>(!!T 'value') cil managed
{
.maxstack 8
IL_0000: ldarg.0
IL_0001: box !!T
IL_0006: unbox.any !!U
IL_000b: ret
}
But for generic code above, the more efficient IL representation should be:
IL_0000: ldarg.0
IL_0001: box !!T
IL_0006: ret
It is known from the constraints that the value is boxed into reference type. Unbox.any
opcode is completely redundant because after box
opcode the value at IL stack will already be a valid reference to !!U
, that can be used without any unboxing.
Why does C# 3.0 compiler doesn't use constraints metadata to emit more efficient generic code? Unbox.any gives a small overhead (just 4x-5x slower), but why not emit better code in this scenario?