从对象中取消装箱值类型

本文关键字:类型 取消装箱 对象 | 更新日期: 2023-09-27 18:31:09

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

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

里希特, 杰弗里 (2010-02-05).CLR 通过 C# (Kindle 位置 4167-4171). 奥莱利媒体 - A. 点燃版.

从对象中取消装箱值类型

为了装箱一个 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但是当它被拆箱时,它永远不会复制到任何地方,只是在其上调用一个方法。 您可以从结构中提取一个属性/字段并仅复制其中的那一部分,而无需复制整个内容。 这可能看起来有点做作,但仍然不完全荒谬。 也就是说,正如您的报价所暗示的那样,在您拆箱后,它仍然可能会复制结构。