C 裝箱和拆箱

2021-10-25 04:48:12 字數 1990 閱讀 4846

c#中值型別和引用型別都可以和object型別進行轉換;

在堆上分配記憶體,用於存放值型別資料;

發生一次記憶體賦值,將資料賦值到堆上的記憶體位址;

轉換結果是對堆上的新儲存位置的引用;

先檢查已裝箱的值的型別和要拆箱成的值型別是否相容,然後賦值堆中儲存的值;

除了通過c#**識別這些轉換,開發者還可以通過cil在乙個特定的**片段中統計box/unbox指令的數量;

vs c# 如何檢視il**

裝箱和拆箱因為會涉及到堆記憶體的申請,所以頻繁的裝箱拆箱會引起gc,從而影響cpu效能和記憶體;

比如,建立乙個arraylist,它維護的是物件引用列表,但是如果在列表中新增值型別如整數,就會造成對值的裝箱以獲取引用;

int totalcount;

arraylist list = new arraylist();

console.write("enter a number between 2 and 1000");

totalcount = int.parse(console.readline());

list.add((double)0);

list.add((double)1);

for (int count = 2; count < totalcount; count++)

foreach (double count in list) , ");

}

每個裝箱操作都涉及記憶體分配和複製,每個拆箱操作都涉及型別檢查和複製,如果用已拆箱的型別做同樣的事情,記憶體分配和型別檢查就可以避免了;

對於簡單的賦值而言,裝箱和拆箱過程需要進行大量的計算;裝箱和拆箱的效能問題主要通過泛型來解決;

在c#中,一些內建的基礎值型別如int、bool等都是不可變型別,字串也是不可變型別;struct既可能是可變型別,也可能是不可變型別,這要取決於其內部實現;

如下,這裡實現了乙個結構體,通過對moveto方法的實現將其變為了乙個可變值型別;

在main函式內,第一次列印結果,是將乙個裝箱後的結果進行拆箱,最終結果為25;

第二次列印結果,首先對拆箱後的值進行了修改,但是要注意,拆箱只是建立了乙個值的副本,列印結果是又重新進行了拆箱,即重新建立了副本,因此列印值還是25;

第三次列印結果,因為介面是乙個引用型別,所以需要先進行裝箱,改動的值是改動裝箱後的堆上的值,而對angle本身不會有修改,因此列印值還是25;

最後一次列印結果,因為都是引用型別,所以沒有裝箱操作,列印時的拆箱直接獲取堆上已經被修改的值,所以列印值為26;

結論:可變的值型別很容易讓人迷惑,因為往往修改的是值的副本,而不是真正想要修改的儲存位置,如果在第一時間避免面使用可變的值型別,就可以消除這種形式的迷惑;

inte***ce iangle 

struct angle : iangle }

int _hours;

public int minutes }

int _minutes;

public int seconds }

int _seconds;

public angle(int hours, int minutes, int seconds)

public void moveto(int hours, int minutes, int seconds)

}class program

}

在接收者是值型別的情況下呼叫方法,需要建立乙個值型別的變數,從而傳遞儲存位置;c#編譯器會建立乙個新的臨時儲存位置,並將值從箱子複製到新位置,是臨時儲存位置成為所需變數,每次進行「拆箱後呼叫」,不管方法是否要修改變數,都會重複以下過程:對已裝箱的值進行型別檢查,拆箱以生成裝箱值的儲存位置,分配臨時變數,將值從箱子複製到臨時變數,再呼叫方法並傳遞臨時儲存位置。但是,如果方法不修改變數,很多開銷都可以避免,就可以不用再拆箱;

將值型別的例項作為接收者來呼叫object生命的虛方法tostring()會發生什麼,這裡其實不一定會發生裝箱和拆箱,取決於多種情況:

c 裝箱和拆箱

c 裝箱和拆箱 概念 裝箱 將值型別轉換為引用型別的過程叫做裝箱 值型別 引用型別 相反,拆箱 將引用型別轉換為值型別 叫做拆箱 引用型別 值型別 裝箱例子 int i 2008 object obj i console.writeline 1 i的值為,裝箱之後的值 i,obj i 927 con...

C 裝箱和拆箱

1 什麼是裝箱和拆箱 裝箱是將值型別轉換為引用型別 拆箱是將引用型別轉換為值型別 2 什麼時候需要裝箱?值型別是高效輕量的型別,因為預設情況下在堆上不包括他們的物件元件,然而,如果我們需要物件元件,這個時候就需要裝箱了。最常見的場景就是 乙個方法你希望能共用,設定的引數型別是object型別 引用型...

C 裝箱和拆箱

值型別例項進行裝箱時的步驟 1 在託管堆中分配記憶體。需要注意的是,由於是將值型別進行引用型別化,因而分配的記憶體空間除了值型別各個欄位所需的記憶體之外,還要加上託管堆所有物件都有的兩個額外成員 型別物件指標和同步塊索引 所需的記憶體。2 將值型別的字段複製到新分配的堆記憶體中。3 返回物件位址,即...