在C#中使用泛型时,拳击 [英] Boxing when using generics in C#
问题描述
我有以下简单的C#代码:
I have the following simple C# code:
private Stack<Person> m_stack = new Stack<Person>();
public void Add<T>(T obj)
where T : Person
{
m_stack.Push(obj);
}
这将产生以下的IL代码:
This will produce the following IL code:
.method public hidebysig instance void
Add<(ConsoleApplication1.Person) T>(!!T obj) cil managed
{
// Code size 20 (0x14)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld class [System]System.Collections.Generic.Stack`1<class ConsoleApplication1.Person> ConsoleApplication1.Pool::m_stack
IL_0007: ldarg.1
IL_0008: box !!T
IL_000d: callvirt instance void class [System]System.Collections.Generic.Stack`1<class ConsoleApplication1.Person>::Push(!0)
IL_0012: nop
IL_0013: ret
} // end of method Pool::Add
所以我的问题是......为什么拳击? (IL_0008)我可以理解向下转换甚至是编译错误,但为什么拳击(人是引用类型...)
So my question is... why boxing? (IL_0008) I can understand downcasting or even compile error, but why boxing (Person is a reference type...)
谢谢!
推荐答案
从ECMA-335分区III 4.1
Excerpt from Ecma-335 Partition III 4.1
如果摘录的 typeTok 的是引用类型,盒子指令不执行。
If typeTok is a reference type, the box instruction does nothing.
其中的 typeTok 是!牛逼的你的情况。
我的猜测是,当编译器编译的代码,它总是调用的盒的操作数的类型,无论是否是参考类型或没有。由于语义的复选框的指令,预期的结果总是保证。
My guess is that when the compiler compiles the code, it always calls box regardless whether the type of the operand is reference type or not. Because of the semantic of the box instruction, the desired result is always guaranteed.
这篇关于在C#中使用泛型时,拳击的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!