相关疑难解决方法(0)

在C#中使用泛型时的装箱

我有以下简单的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是引用类型...)

提前致谢!

c# generics

12
推荐指数
2
解决办法
1642
查看次数

为什么'box'指令是针对泛型发出的?

这是一个相当简单的泛型类.通用参数被约束为引用类型.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)

c# generics il

11
推荐指数
2
解决办法
603
查看次数

标签 统计

c# ×2

generics ×2

il ×1