C# 在分配泛型类型时发出 box/unbox?
C# emits box/unbox when assigning generic types?
我刚刚偶然发现了为以下示例发出的奇怪 IL 代码:
class Sample
{
void Foo<T,U>(T t, U u) where U : T { t = u; }
}
为 Foo 主体发出的 IL 是
IL_0001: ldarg.2 // u
IL_0002: box !!1/*U*/
IL_0007: unbox.any !!0/*T*/
IL_000c: starg.s t
所以我的问题是:为什么它会发出 unboxing/boxing 操作?我想对话永远不需要任何装箱,因为它首先是引用类型,或者无论如何都是完全相同的数据类型。
更奇怪的是,即使我明确说类型参数是引用类型,也不会以任何方式改变发出的代码:
class Sample
{
void Foo<T, U>(T t, U u) where U : class, T where T : class { t = u; }
}
(IL输出相同)
那么..为什么?
T
可以是引用类型(接口,object
或 System.ValueType
),而 U
是结构,例如
Foo<IConvertible, int>(1, 2);
Foo<object, int>("foo", 2);
我刚刚偶然发现了为以下示例发出的奇怪 IL 代码:
class Sample
{
void Foo<T,U>(T t, U u) where U : T { t = u; }
}
为 Foo 主体发出的 IL 是
IL_0001: ldarg.2 // u
IL_0002: box !!1/*U*/
IL_0007: unbox.any !!0/*T*/
IL_000c: starg.s t
所以我的问题是:为什么它会发出 unboxing/boxing 操作?我想对话永远不需要任何装箱,因为它首先是引用类型,或者无论如何都是完全相同的数据类型。
更奇怪的是,即使我明确说类型参数是引用类型,也不会以任何方式改变发出的代码:
class Sample
{
void Foo<T, U>(T t, U u) where U : class, T where T : class { t = u; }
}
(IL输出相同)
那么..为什么?
T
可以是引用类型(接口,object
或 System.ValueType
),而 U
是结构,例如
Foo<IConvertible, int>(1, 2);
Foo<object, int>("foo", 2);