从对象中取消装箱值类型

Tar*_*rik 6 .net c# clr unboxing

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

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

里希特,杰弗里(2010-02-05).CLR通过C#(Kindle Locations 4167-4171).OReilly Media - A. Kindle版.

Ser*_*rvy 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();
}
Run Code Online (Sandbox Code Playgroud)

MyStruct为盒装入obj,但是当它的拆箱它从来没有任何数据的拷贝,一个方法是简单地调用就可以了.你可以将一个属性/字段从结构中拉出来并复制它的那一部分而不需要复制整个东西.这可能看起来有点做作,但它仍然不完全荒谬.也就是说,正如你的引言所暗示的那样,在拆箱后它仍然可能会复制结构.

  • 我在Visual Studio 2010中编译(在使用字段初始化程序更正错误之后)示例代码,当我使用Reflector查看生成的IL时,在调用Foo()之前,未装箱的MyStruct实际上已复制到临时局部变量.知道为什么吗? (2认同)