从对象中取消装箱值类型

时间:2012-04-14 02:03:09

标签: c# .net clr unboxing

我一直试图理解这一段,但不知怎的,我无法在脑海中虚拟化它,有些人请详细说明一点:

  

拆箱不是拳击的反面。拆箱操作   比拳击便宜得多。拆箱真的只是操作   获取指向包含的原始值类型(数据字段)的指针   在一个对象内。实际上,指针指的是未装箱的部分   在盒装实例中。因此,与拳击不同,拆箱不涉及   复制内存中的任何字节。使这一点变得重要   澄清,重要的是要注意拆箱操作   通常后面会复制字段。

     

Richter,Jeffrey(2010-02-05)。 CLR通过C#(Kindle位置   4167-4171)。 OReilly Media - A. Kindle版。

1 个答案:

答案 0 :(得分:6)

为了打包一个int,你需要在堆上创建一个足够大的对象来保存struct所拥有的所有数据。在堆上分配新对象意味着GC可以找到一个位置,并且可以让GC在其生命周期内和之后对其进行清理/移动。这些操作虽然不是超级昂贵,但也不便宜。

要取消装箱值类型,您所做的就是取消引用指针,可以这么说。您只需要查看引用(这是您拥有的object)来查找实际值的位置。在内存中查找值非常便宜,这就是为什么该段说'拆箱'很便宜。

更新

虽然未装箱的值类型通常会在取消装箱后立即复制到其他位置,但情况并非总是如此。请考虑以下示例:

public struct MyStruct
{
  private int value = 42;
  public void Foo()
  {
    Console.WriteLine(value);
  }
}

static void Main()
{
  object obj = new MyStruct();
  ((MyStruct)obj).Foo();
}

MyStruct被装入obj,但是当它被取消装箱时,它永远不会被复制到任何地方,只需在其上调用一个方法。你可以将一个属性/字段从结构中拉出来并复制它的那一部分而不需要复制整个东西。这可能看起来有点做作,但它仍然不完全荒谬。也就是说,正如你的引言所暗示的那样,在拆箱后它仍然可能会复制结构。