C#值類型和引用類型這個概念在剛學習的時候應該就知道了。但是我們並沒有深入的去理解它。越是基礎知識其實才是最有用的。對代碼的優化,代碼質量的提升都有幫助。通過整理本文章,對很多知識也起到了鞏固的作用吧。 1,值類型 值類型有:整型,浮點型,十進位,布爾型,struct,枚舉。值類型是線上程棧上分配的 ...
C#值類型和引用類型這個概念在剛學習的時候應該就知道了。但是我們並沒有深入的去理解它。越是基礎知識其實才是最有用的。對代碼的優化,代碼質量的提升都有幫助。通過整理本文章,對很多知識也起到了鞏固的作用吧。
1,值類型
值類型有:整型,浮點型,十進位,布爾型,struct,枚舉。值類型是線上程棧上分配的,值類型也稱輕量級類型,一個值類型的變數就包含了值類型的值,所以它沒有引用類型的指針。所有值類型的數據都無法為null,所以我們聲明時必須賦初始值。
2,引用類型
引用類型有:class(類),interface(介面),delegate(委托),object,string,數組。引用類型是在托管堆上分配的,我們常用的new操作符會返回一個對象的指針,也就是對象數據在記憶體中的地址的一個引用。引用類型的傳遞其實就是傳遞對象的指針。引用類型在創建時預設為null,也就是當前變數不指向一個有效的對象,這時如果我們去讀取null對象里的屬性值時就會出現我們常遇見的異常:“未將對象的引用設置到對象的實例”,是不是很熟悉。所以在實際開發中我們在操作對象的時候一定要先判斷該對象是不是為null,避免異常。
值類型和引用類型我們用的都比較多,那肯定就避免不了裝箱和拆箱操作。
3,什麼是裝箱?
裝箱就是值類型轉為引用類型。
4,什麼是拆箱?
拆箱就是引用類型轉為值類型。這裡要註意兩點:
4.1,只有被裝箱過的對象才能被拆箱。
4.2,一個對象拆箱後只能還原為未裝箱之前的類型。看下麵代碼:
1 int i = 5; 2 object obj = i;//裝箱操作 3 Int16 j = (Int16)obj;//拆箱操作
我們先給i做了裝箱操作。然後在拆箱。但是還原的是Int16類型,這裡就會拋出異常:“指定的轉換無效”。
5,有的同學說裝箱和拆箱都影響性能,那麼到底是裝箱影響呢還是拆箱影響呢還是都影響呢?
5.1,裝箱都發生了什麼呢:
1,首先在托管堆中分配好記憶體,分配的記憶體量是值類型欄位需要的記憶體量加上托管堆上需要的對象的兩個額外成員(對象指針,同步塊索引)需要的記憶體。
2,值類型的欄位複製到新分配的記憶體中。
3,返回對象的地址,也就是對象的引用。
5.2,拆箱都發生了什麼呢:
1,獲取已裝箱的值類型實例的指針。
2,把獲取到的值複製到棧。
所以裝箱時比較耗費性能的,還有可能引發一次GC操作,而拆箱只是一個獲取指針的過程耗費資源比裝箱要小的多。正因為值類型有裝箱拆箱操作,所以像ArrayList這樣的集合性能時非常令人擔憂的,所以C#2.0出現的泛型:List<>,減少了裝箱拆箱操作。
6,應用場景
首先不止時面試的時候會經常問到應用場景這個問題,我們平時寫程式的時候也很清楚,大多情況下我們都會使用引用類型。那什麼時候會使用值類型呢?
6.1,類型不會有被繼承的可能,也不會繼承其他的類型。
6.2,類型的實例比較小,不會被做為方法的參數,不會被頻繁賦值。
本文就到此結束了。感覺自己也學到了不少東西,以後沒事的時候也可以拿來看看,同時呢也希望可以幫助到需要的人,如有錯誤的地方還望大神指點,繼續加油!
原文來自:C#基礎知識1-深入理解值類型和引用類型-曾亞平個人博客