2012-04-14 102 views
5

我一直在试图理解这一段,但不知何故,我不能在我的脑海虚拟化了,有人请详细说明这一点:拆箱值类型

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

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

+0

在阅读段落 – zinking 2013-06-26 08:26:28

回答

6

为了填充一个int,你需要在堆上创建一个足够大的对象来存放该结构所拥有的所有数据。在堆上分配一个新对象意味着GC为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但是当它的拆箱它从来没有任何数据的拷贝,一个方法是简单地调用就可以了。同样,你可以将一个属性/字段从结构中取出,只需复制其中的一部分而不需要复制整个结构。这可能看起来有点做作,但它仍然不是完全荒谬的。也就是说,正如你的引用暗示的那样,在解开它之后仍然可能复制结构体。

+0

时有完全相同的问题但是在找到值之后,这些值将被复制回堆栈,这是否正确? – Tarik 2012-04-14 02:53:45

+0

@Braveyard不,那不是。一旦价值被拆箱,它将被复制,但它并不需要。此外,它可能不会被复制回堆栈,它可能被复制到堆上某个其他引用类型的字段中。 – Servy 2012-04-14 03:34:45

+0

我在答案中添加了一个代码示例。 – Servy 2012-04-14 03:40:31