1. 程式人生 > >c#裝箱拆箱

c#裝箱拆箱

裝箱和拆箱是值型別和引用型別之間相互轉換是要執行的操作。 

1. 裝箱在值型別向引用型別轉換時發生

2. 拆箱在引用型別向值型別轉換時發生

光上述兩句話不難理解,但是往深處瞭解,就需要一些篇幅來解釋了。

我們先看裝箱時都會發生什麼事情,下面是一行最簡單的裝箱程式碼

object obj = 1;

這行語句將整型常量1賦給object型別的變數obj; 眾所周知常量1是值型別,值型別是要放在棧上的,而object是引用型別,它需要放在堆上;要把值型別放在堆上就需要執行一次裝箱操作。

這行語句的IL程式碼如下,請注意註釋部分說明:

.locals init (

[0] object objValue

//以上三行IL表示宣告object型別的名稱為objValue的區域性變數

IL_0000: nop

IL_0001: ldc.i4.s 9 //表示將整型數9放到棧頂

IL_0003: box [mscorlib]System.Int32 //執行IL box指令,在記憶體堆中申請System.Int32型別需要的堆空間

IL_0008: stloc.0 //彈出堆疊上的變數,將它儲存到索引為0的區域性變數中

以上就是裝箱所要執行的操作了,執行裝箱操作時不可避免的要在堆上申請記憶體空間,並將堆疊上的值型別資料複製到申請的堆記憶體空間上,這肯定是要消耗記憶體和cpu資源的。我們再看下拆箱操作是怎麼回事:

請看下面的C#程式碼:

object objValue = 4;

int value = (int)objValue;

上面的兩行程式碼會執行一次裝箱操作將整形數字常量4裝箱成引用型別object變數objValue;然後又執行一次拆箱操作,將儲存到堆上的引用變數objValue儲存到區域性整形值型別變數value中。

同樣我們需要看下IL程式碼:

.locals init (

[0] object objValue,

[1] int32 'value'

) //上面IL宣告兩個區域性變數object型別的objValue和int32型別的value變數

IL_0000: nop

IL_0001: ldc.i4.4 //將整型數字4壓入棧

IL_0002: box [mscorlib]System.Int32  //執行IL box指令,在記憶體堆中申請System.Int32型別需要的堆空間

IL_0007: stloc.0 //彈出堆疊上的變數,將它儲存到索引為0的區域性變數中

IL_0008: ldloc.0//將索引為0的區域性變數(即objValue變數)壓入棧

IL_0009: unbox.any [mscorlib]System.Int32 //執行IL 拆箱指令unbox.any 將引用型別object轉換成System.Int32型別

IL_000e: stloc.1 //將棧上的資料儲存到索引為1的區域性變數即value

拆箱操作的執行過程和裝箱操作過程正好相反,是將儲存在堆上的引用型別值轉換為值型別並給值型別變數。

裝箱操作和拆箱操作是要額外耗費cpu和記憶體資源的,所以在c# 2.0之後引入了泛型來減少裝箱操作和拆箱操作消耗。

相關推薦

C#裝箱,和強制轉換(轉)

出處:https://www.cnblogs.com/fengjiulin110120/p/6605739.html 關係: 強制轉換就包含有裝箱拆箱操作,裝箱就是把值型別轉換成引用型別,反之就是拆箱.   一:  裝箱和拆箱: 裝箱是把值型別轉換成引用型別,而拆箱是把引用型別轉換成值型別

C#裝箱效能認識

using System; using System.Collections.Generic; using System.Text; using System.Collections; using S

c#裝箱

裝箱和拆箱是值型別和引用型別之間相互轉換是要執行的操作。  1. 裝箱在值型別向引用型別轉換時發生 2. 拆箱在引用型別向值型別轉換時發生 光上述兩句話不難理解,但是往深處瞭解,就需要一些篇幅來解釋了。 我們先看裝箱時都會發生什麼事情,下面是一行最簡單的裝箱程式碼

c#裝箱詳解

裝箱拆箱說簡單點就是值型別轉換成引用型別與引用型別轉換成值型別。 說複雜一點: 例如裝箱,在建立值型別的時候會在棧上儲存一個值,在堆上也會儲存一個隱藏的引用型別,這個隱藏的引用型別就是供裝箱的時候引用型別直接引用的值,所以原來的值型別的值不受影響,拆箱與裝箱一樣,在建立引

C#中的裝箱

局部變量 bsp -s spa clas 發生 app 拆箱 b-s 在C#中,經常需要把值類型和引用類型相互轉換。 首先明確兩條法則: 1.引用類型總是被分配到“堆”上。 2.值類型總是分配到它聲明的地方: a.作為引用類型的成員變量分配到“堆”上 b.作

C#的裝箱,以及裝箱的效能問題

1:什麼事裝箱和拆箱:比如  int    i   = 0  ; object   o;     o = i;  //將具體的整型變數賦值個一個object,把子類的值

c#中的值型別和引用型別 裝箱 (好文)

  一,c#中的值型別和引用型別      眾所周知在c#中有兩種基本型別,它們分別是值型別和引用型別;而每種型別都可以細分為如下型別:       什麼是值型別和引用型別 什麼是

C# struct 裝箱例子

值型別:拆箱、裝箱 struct是值型別 struct和class的區別 類是引用型別,struct是值型別 在託管堆上建立類的例項,在棧上建立struct例項 類例項的賦值,賦的是引用地址

C#==>型別轉換 與 裝箱

1,型別轉換,C#有兩種轉化方式,隱式轉換和顯式轉換      只要能保證值不會發生任何變化轉換就可以自動進行。      這裡很重要一點就是要保證資料沒有丟失,只要沒有丟失,編譯器就可以執行下去 ①隱式轉換 byte value1 = 10; byte value2 =

C#的裝箱

深入理解C#的裝箱和拆箱 裝箱拆箱的定義 裝箱和拆箱是值型別和引用型別之間相互轉換時要執行的操作。 1. 裝箱在值型別向引用型別轉換時發生。 2. 拆箱在引用型別向值型別裝換是發生。 光上述兩句話不難理解,但是往深處瞭解,就需要一些篇幅來解釋了。

C#筆記--裝箱

using System; /** * C#中牛逼的拆箱和裝箱機制,裝箱只需要隱式轉換,拆箱需要顯示轉換。 * * 感覺拆箱和裝箱在程式語言裡面最大的作用是可以把任何東西都看做物件處理。 */ namesp

Java之集合初探(二)Iterator(叠代器),collections,打包/解包(裝箱),泛型(Generic),comparable接口

基本 generate 等於 框架 ring bin list() each 是否 Iterator(叠代器) 所有實現了Collection接口的容器都有一個iterator方法, 用來返回一個實現了Iterator接口的對象 Iterator對象稱作叠代器, 用來

裝箱

print static write otf obj highlight new 文件寫入 tput 步驟 :裝箱(1)先將數據裝箱實體對象.    (2)多個實體對象在裝箱給實體.    (3)實體集合在保存到文件拆箱:(1)先將文件中的數據拆給集合    (2)集合拆

理解JDK1.5的自動裝箱

特性 ava 創建 幫我 max 循環 assert rally jdk1 JDK1.5的升級引入了裝箱和拆箱概念,簡單說就是為了簡化書寫。   JDK1.5之前,創建Integer對象是需要這麽寫的 Integer i = new Integer("3");   JDK

消息機制的優化----------無需進行裝箱/的 版本

我們 bug try clas email 引用類型 為什麽 cli small 消息機制的優化----------無需進行裝箱/拆箱的 版本 http://www.manew.com/thread-111056-1-1.html 裝箱/拆箱為了解釋“為什麽不用o

教學-44 命名空間和裝箱

add 不同 ace 封裝 text 類庫 store linq source 曾英-C#教學-44 命名空間和裝箱拆箱 目錄 1\認識命名空間,學習如何定義使用命名空間 2\學習如何使用幫助 3\理解裝箱和拆箱操作 1\命名空間 以下都是.Net內

自動裝箱(Autoboxing,Unboxing)

包裝類 iter oracl ble 類型 doc section tps 技術 自動裝箱和拆箱 https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html 1.5才有(Autoboxing,Unb

java之裝箱

img 類類型 需要 子類 ble package static ger 編譯錯誤 參考http://how2j.cn/k/number-string/number-string-wrap/22.html 封裝類 所有的基本類型,都有對應的類類型 比如int對應的類是In

Java的==和equals()以及自動裝箱

char AC oid name span 兩個 也會 掌握 word 拋一個問題 大家先看下面的代碼,先不要看答案自己做一下: public class AutoboxingTest { public static void main(String[] args)

可變引數 裝箱

<span style="font-size:18px;">/* 可變引數要注意的事項: 呼叫該方法時候,可以傳遞引數也可以不傳 可變引數是一個數組物件 可變引數必須位於最後一個 一個函式最多隻能有一個可變引數,因為可變引數必須在形參中的最後一個 */