CLR支持兩種類型:引用類型和值類型。 引用類型總是從托管堆上分配,值類型一般線上程棧上分配。 在.NET Framework SDK中指出,任何稱為類的類型都是引用類型,所有值類型都成為結構或枚舉 以下代碼演示值類型與引用類型區別 值類型與引用類型的一些區別 值類型有已裝箱和未裝箱兩種形式,,引用 ...
CLR支持兩種類型:引用類型和值類型。
引用類型總是從托管堆上分配,值類型一般線上程棧上分配。
在.NET Framework SDK中指出,任何稱為類的類型都是引用類型,所有值類型都成為結構或枚舉
以下代碼演示值類型與引用類型區別
class someref { public int x;//引用類型 } struct someval { public int x;//值類型 } namespace 值類型_引用類型 { class Program { static void Main(string[] args) { someref r1 = new someref();//在堆上分配 someval v1 = new someval();//在棧上分配 r1.x = 5;//提領指針 v1.x = 5;//在棧上修改 Console.WriteLine(r1.x);//顯示5 Console.WriteLine(v1.x);//顯示5 Console.ReadKey(); someref r2 = r1;//只複製引用(指針) someval v2 = v1;//在棧上從新分配並複製成員 r1.x = 8;//r1,r2會同時改變,因為r1跟r2指向同一個東西 v1.x = 9;//只改變v1,v2不變,因為v1,v2是兩個東西 Console.WriteLine(r1.x);//顯示8 Console.WriteLine(r2.x);//顯示8 Console.WriteLine(v1.x);//顯示9 Console.WriteLine(v2.x);//顯示5 } } }
值類型與引用類型的一些區別
值類型有已裝箱和未裝箱兩種形式,,引用類型總是處於已裝箱形式。
值類型從System.ValueType派生,該類型直接從System.Object派生,他重寫了System.Object的Equals和GetHashCode方法。
值類型不能作為基類定義一個新的基類型或者引用類型,所以不能再值類型中引入新的虛方法,所有方法不能是抽象的,所有方法都不能重寫。
引用類型的變數包含的是堆上的一個對象的地址。預設創建時被初始化為null,表明引用類型的變數當前不指向一個有效的對象。值類型的標量重視包含其基礎類型的一個值,而且
值類型的所有成員都初始化為0,。
將一個值類型的變數賦給另一個值類型變數時會進行一次逐欄位的複製。將引用類型的變數賦給另一個引用類型時,只複製記憶體地址(如上例)。
基於上一條,可能會有多個引用類型變數引用堆中的同一個對象,所以對一個變數的操作可能會影響其他變數引用的對象。相反值類型不會。
由於未裝箱的值類型不在堆上分配,當定義該類型的方法不處於活動狀態時就會被釋放,也不會通過Finalize方法接收到通知。