6

我一直在尝试理解这一段,但不知何故我无法在脑海中虚拟化它,请有人详细说明一下:

拆箱与装箱并不完全相反。拆箱操作比装箱成本低得多。拆箱实际上只是获取指向对象中包含的原始值类型(数据字段)的指针的操作。实际上,指针指向已装箱实例中未装箱的部分。因此,与装箱不同,拆箱不涉及复制内存中的任何字节。做出这一重要说明后,请务必注意,拆箱操作通常会在复制字段之后进行。

杰弗里里希特 (2010-02-05)。通过 C# 进行 CLR(Kindle 位置 4167-4171)。OReilly Media - A. Kindle 版。

4

1 回答 1

6

为了对 int 进行装箱,您需要在堆上创建一个足够大的对象,以容纳结构所保存的所有数据。在堆上分配一个新对象意味着让 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但是当它被拆箱时,它永远不会被复制到任何地方,只是在它上面调用一个方法。同样,您可以将属性/字段从结构中拉出并仅复制其中的一部分,而无需复制整个内容。这可能看起来有点做作,但仍然不完全荒谬。也就是说,正如您的报价所暗示的那样,在您将其拆箱后,它仍然可能会复制该结构。

于 2012-04-14T02:15:13.110 回答