2011-01-25 36 views
11

可能重複:
Why do we need boxing and unboxing in C#?
What is boxing and unboxing and what are the trade offs?Box和UnBox是什麼意思?

在C#什麼母鹿坐手段: 「框和拆箱」?

這裏是我創建文本的MSDN摘錄。

但是這種便利是有代價的。 添加到ArrayList的任何引用或值類型 都隱式地上傳到Object。如果這些項目的值類型爲 ,則在 將它們添加到列表中時它們必須裝箱,並且 在檢索它們時取消裝箱。 鑄造和拳擊和 拆箱操作減少 表現;在 場景中,裝箱和 拆箱的效果可能非常顯着,您必須迭代 大型館藏。

謝謝!

+0

[爲什麼我們需要在C#中裝箱和拆箱?](http://stackoverflow.com/questions/2111857/why-do-we-need-boxing-and-unboxing-in-c)和[用例在C#中裝箱值類型](http://stackoverflow.com/questions/1028520/use-cases-for-boxing-a-value-type-in​​-c/1028549#1028549)。 – jason 2011-01-25 14:35:42

+0

同樣重複http://stackoverflow.com/questions/13055/what-is-boxing-and-unboxing-and-what-are-the-trade-offs/25324#25324 – 2011-01-25 14:38:25

回答

26

下面是關於Common Language Runtime內部的更詳細的解釋。

首先,讓我們值類型引用類型之間的區別:

  • 值類型是舉行堆棧上和它的一個副本傳遞給調用的方法
  • 參考值保存在託管堆中,堆棧僅保存指向其位置的指針(引用)。的位置,而不是對象,傳遞給調用的方法

如果你不知道堆棧是什麼(不要生氣),它是保持在方法和地址局部變量的存儲區域用於return指令的呼叫者功能(僅作簡要說明並提供一般答案)。當你調用一個方法時,堆棧上的足夠區域是靜態分配給它的,所以堆棧分配總是被稱爲靜態分配。

堆,取而代之的,是從棧中分離的存儲區域,正在運行的進程的財產,其中分配必須首先要求的操作系統,這就是爲什麼它被稱爲動態分配(如果您不要在if語句中運行,例如,可能不會爲您的進程分配內存,而是始終分配堆棧)。

只需做出最終例如在堆和棧:在語言如C++,宣告int[100] a;堆棧(64位系統假定)上靜態地分配100 * 8個字節,而int* a = new int[100];聲明瞭一個8個字節(上64-並且在堆上請求800個更多的字節,如果可用的話。

現在讓我們來談談C#:

拳擊

由於int是值類型,並在棧上分配,當你將它轉換爲對象或其他任何引用類型(實際上沒有其他int可以繼承的引用類型,但這是一條通用規則),該值必須成爲引用類型。因此,堆中的新區域被分配,其中的對象是盒裝的,堆棧中保存着一個指向它的指針。

拆箱

正好相反:當你有一個引用類型,如對象,並希望將其轉換爲一個值類型,如int,則新的值必須保持在棧上,所以CLR去堆,取消箱的價值,並將其複製到堆棧。

換句話說

記住int[]int*的例子嗎?簡單地說,當你在C#中有int時,運行時期望它的堆棧位置爲,其值爲,但是當你有object時,它希望它的實際值位於堆棧指向的堆位置。

0

ArrayList只存儲對象。對於引用類型(如String),這是沒有問題的,但對於ValueType(int,DateTime,..)來說,它是。

這些值類型需要先轉換爲對象,然後才能將它們存儲爲普通對象。這個「轉換爲對象」被稱爲「拳擊」,需要一點時間。

當您讀取數值時,您需要將Object從Object轉換爲int(或其它)。這被稱爲「拆箱」。

1

.net Framework有兩種不同的類型。

值類型 如int,雙,單

引用類型 的ArrayList 列表 和類型的許多,許多

變量值類型被存儲在堆棧 ReferenceTyped變量存儲在堆中

變量類型的值類型存儲值 ReferenceTyped變量存儲的參考值

因此,如果您複製值類型變量 - 有一個值 但如果一個真正副本您複製了變量ReferenceType變量 - 您將得到一個附加參考到SAME變量。

拳擊在你的問題意味着,一個valueType變量(例如int)將被處理喜歡參考類型變量 - .net將它放入一個新的。所以它會被封裝在堆中,並且會有參考。

如果您希望該值再次處於valueType變量中,您必須取消箱(取出箱子)。所以這個值將被從堆中取出 - 並再次存儲/提供給堆棧。

+1

「類型ValueTypes的變量存儲在堆疊「不,通常不是。它們通常存儲在參考類型的對象內,生活在堆上。 – 2014-12-22 22:39:06