我有以下简单的C#代码:
private Stack<Person> m_stack = new Stack<Person>();
public void Add<T>(T obj)
where T : Person
{
m_stack.Push(obj);
}
Run Code Online (Sandbox Code Playgroud)
这将产生以下IL代码:
.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
Run Code Online (Sandbox Code Playgroud)
所以我的问题是......为什么拳击?(IL_0008)我可以理解向下转换甚至编译错误,但为什么拳击(Person是引用类型...)
提前致谢!
这是一个相当简单的泛型类.通用参数被约束为引用类型.IRepository并且DbSet还包含相同的约束.
public class Repository<TEntity> : IRepository<TEntity>
where TEntity : class, IEntity
{
protected readonly DbSet<TEntity> _dbSet;
public void Insert(TEntity entity)
{
if (entity == null)
throw new ArgumentNullException("entity", "Cannot add null entity.");
_dbSet.Add(entity);
}
}
Run Code Online (Sandbox Code Playgroud)
编译的IL包含box指令.这是发布版本(虽然调试版本也包含它).
.method public hidebysig newslot virtual final
instance void Insert(!TEntity entity) cil managed
{
// Code size 38 (0x26)
.maxstack 8
IL_0000: ldarg.1
>>>IL_0001: box !TEntity
IL_0006: brtrue.s IL_0018
IL_0008: ldstr "entity"
IL_000d: ldstr "Cannot add null entity."
IL_0012: …Run Code Online (Sandbox Code Playgroud)