C# 引用類型和值類型 CLR支持兩種類型:引用類型和值類型。 1.引用類型 (1)記憶體必須從托管堆上分配; (2)堆上分配的每個對象都有一些額外成員(包括“類型對象指針”,“同步塊索引”),這些成員必須初始化; (3)對象的其他位元組總是設為零; (4)從托管堆分配對象時,可能強制執行一次垃圾回收。 ...
C# 引用類型和值類型
CLR支持兩種類型:引用類型和值類型。
1.引用類型
(1)記憶體必須從托管堆上分配;
(2)堆上分配的每個對象都有一些額外成員(包括“類型對象指針”,“同步塊索引”),這些成員必須初始化;
(3)對象的其他位元組總是設為零;
(4)從托管堆分配對象時,可能強制執行一次垃圾回收。
2.值類型
(1)一般線上程棧上分配;
(2)不受垃圾回收器控制;
3.兩者的區別
(1)值類型的兩種表示形式:未裝箱和已裝箱,引用類型都是已裝箱;
(2)值類型從System.ValueType派生,提供了與System.Object相同的方法,但是重寫了Equals和GetHashCode方法;
(3)由於值類型不能作為基類型,所以不應在值類型中使用虛方法;
(4)引用類型包含堆中對象的地址,預設為null;
(5)將值類型變數賦值給另外一個值類型變數,會複製每個欄位的值,而引用類型則只複製記憶體地址,所以改變值類型的複製對象不會影響原值,但是引用類型會改變原值;
(6)由於未封裝的值類型不在堆上分配,如果分配後該類型的事例不再活動,其記憶體就會被釋放。
4.裝箱
定義:將值類型轉換成引用類型。
(1):在堆記憶體中分配值類型各欄位所需的記憶體加上額外成員(類型對象指針和同步塊索引)所需的記憶體;
(2):值類型的欄位複製到新分配的對記憶體;
(3):返回對象地址。
5.拆箱
定義:將引用類型轉換為值類型。
(1):獲取已裝箱事例的各欄位值;
(2):將欄位包含的值從堆複製到棧的值類型。
註意:
(1):如果已裝箱事例的引用為null,拋出NullReferenceException異常;
(2):如果引用的對象不是所需值類型的已裝箱實例,拋出InvalidCastException異常。
例如:
1 public static void Main() 2 { 3 Int32 x = 5; 4 Object o = x; 5 Int64 y = (Int64) (Int32) o; 6 }