關於值類型和引用類型已經有很多人寫了很多文章,但是很多人也只是停留在字面上的理解,如果采用一種通俗的方法來解釋,想必很多人都會理解。我們都知道值類型存儲在棧上,引用類型存儲在堆上,引用類型都是xxx類,值類型都是xxx結構(structure)。下面先放一張圖
// 引用類型 因為有class class SomeRef { public Int32 x; } // 值類型 因為是struct struct SomeVal { public Int32 x; } static void ValueTypeDemo() { SomeRef r1 = new SomeRef(); // 分配在堆上 SomeVal v1 = new SomeVal(); // 分配在棧上 r1.x = 5; v1.x = 5; Console.WriteLine(r1.x); // 結果為"5" Console.WriteLine(v1.x); // 同樣也是 "5" SomeRef r2 = r1; SomeVal v2 = v1; r1.x = 8; v1.x = 9; Console.WriteLine(r1.x); // 結果為"8" Console.WriteLine(r2.x); // 結果為"8" Console.WriteLine(v1.x); // 結果為"9" Console.WriteLine(v2.x); // 結果為"5" }
從代碼和圖可以看的很清楚,下面我們結合裝箱和拆箱談一談值類型和引用類型。
通俗一點的理解
一個應用程序的啟動可以理解為你開了一個商店,商店的店鋪相當於棧,商店的倉庫相當於堆,對於有些小的商品,比如打火機之類的,倉庫就沒必要存貨了,而對於手提箱之類的大件,商店里面只是放一個作為展示,當你去商店里面買東西的時候,直接從商店里那,效率是最快的,你在商店里選好了東西去倉庫里取,效率就會低一些。想必到這里你就會明白堆和棧了。商店倒閉的時候,商店里面的東西要全部進行處理,而倉庫里面的東西需要等待一段時間(GC)。
接下來說一下裝箱和拆箱,由於一些特殊的需要,我們需要把值類型轉換成引用類型(裝箱),引用類型在轉換成值類型(拆箱),比如超市里面存包裹,你的包裹由於不能帶到超市里面,但是你又不能把你包裹扔掉,所以這時候可以給你提供一個箱子,你把你的包裹存到箱子里面(裝箱),然后給你一張存包的卡片,等你購物完成后,就需要憑卡片取出包裹(拆箱)。當然這只是比較通俗的理解,可能跟實際的定義有出入,也希望大家多多提出意見和觀點,把技術通俗話有助於我們的理解。