避免方法调用中的装箱/拆箱

时间:2016-07-21 04:59:30

标签: c#

我试图了解从Essential C#6.0(MarkMichaelis和EricLippert)进行方法调用时拳击/拆箱的影响,最终比我开始时更加困惑。

以下是本书的代码:

struct A
{
    public int Val {get; set;};
    //doesn't override ToString
}

A vo = new A();;
object thing;
// Boxing
thing = vo;
string text = ((A)thing).ToString();
Console.WriteLine(text);

作者接着说:

  

如果接收器未装箱且结构未覆盖   ToString(),必须调用基类实现,并且它   期望引用对象作为其接收者。因此,   接收器是盒装的。

在上面的代码中就是这种情况,其中对A的强制转换运算符将取消装入'thing',然后尝试在临时上调用ToString。由于ToString()方法尚未在结构A中被覆盖,因此只有在再次装入由强制转换(A)生成的临时值或者编译器完全优化取消装箱/装箱后,才会发生对ToString的调用。

但是生成的CIL如下所示,确实表明'thing'已经被取消装箱,但是对ToString()的调用没有被重新装箱。请帮我理解这一点。

.locals init (valuetype Chapter7.A V_0,
           object V_1,
           string V_2,
           valuetype Chapter7.A V_3)
  IL_0000:  nop
  IL_0001:  ldloca.s   V_0
  IL_0003:  initobj    Chapter7.A
  IL_0009:  ldloc.0
  **IL_000a:  box        Chapter7.A** //thing = vo
  IL_000f:  stloc.1
  IL_0010:  ldloc.1
  **IL_0011:  unbox.any  Chapter7.A** //((A)thing)
  IL_0016:  stloc.3
  IL_0017:  ldloca.s   V_3 //the temporary where unboxed value is stored
  IL_0019:  constrained. Chapter7.A
  IL_001f:  callvirt   instance string [mscorlib]System.Object::ToString()

0 个答案:

没有答案