在C#中,根據(jù)這些數(shù)據(jù)類型在內(nèi)存中存儲值的方式對它們進(jìn)行分類。C#包括以下類別的數(shù)據(jù)類型:
值類型
引用類型
指針類型
如果數(shù)據(jù)類型在其自己的內(nèi)存空間中保存數(shù)據(jù)值,則它是一種值類型。這意味著這些數(shù)據(jù)類型的變量直接包含值。
所有值類型都從System.ValueType派生,而System.ValueType又從System.Object派生。
例如,整數(shù)變量 int i = 100;
系統(tǒng)將100存儲在為變量 i 分配的內(nèi)存空間中。下圖說明了如何將100存儲在“i”的內(nèi)存(0x239110)中的某個假設(shè)位置:
以下數(shù)據(jù)類型均為值類型:
bool
byte
char
decimal
double
enum
float
int
long
sbyte
short
struct
uint
ulong
ushort
當(dāng)您將值類型的變量從一種方法傳遞到另一種方法時,系統(tǒng)會在另一種方法中創(chuàng)建變量的單獨副本。如果在一個方法中更改了值,則不會影響另一方法中的變量。
static void ChangeValue(int x) { x = 200; Console.WriteLine(x); } static void Main(string[] args) { int i = 100; Console.WriteLine(i); ChangeValue(i); Console.WriteLine(i); }
100
200
100
在上面的示例中,即使在將 Main ()方法中的變量 i 傳遞給 ChangeValue ()方法并更改其值之后,它仍然保持不變。
與值類型不同,引用類型不會直接存儲其值。相反,它存儲正在存儲值的地址。換句話說,引用類型包含指向另一個保存數(shù)據(jù)的存儲位置的指針。
例如,以下字符串變量:
string s = "Hello World!!";
下圖顯示了系統(tǒng)如何為上述字符串變量分配內(nèi)存。
如上圖所示,系統(tǒng)為變量s選擇內(nèi)存中的隨機位置(0x803200)。變量s的值為0x600000,這是實際數(shù)據(jù)值的內(nèi)存地址。因此,引用類型存儲實際值所在位置的地址,而不是值本身。
以下是引用類型數(shù)據(jù)類型:
字符串
數(shù)組(即使它們的元素是值類型)
類
委托
當(dāng)您將引用類型變量從一個方法傳遞到另一個方法時,它不會創(chuàng)建新的副本; 相反,它會傳遞變量的地址。因此,如果我們改變方法中變量的值,它也會反映在調(diào)用方法中。
static void ChangeReferenceType(Student std2) { std2.StudentName = "Steve"; } static void Main(string[] args) { Student std1 = new Student(); std1.StudentName = "Bill"; ChangeReferenceType(std1); Console.WriteLine(std1.StudentName); }
Steve
在上面的示例中,我們將 Student 對象 std1 傳遞給ChangeReferenceType()方法。在這里,它實際上傳遞std1的內(nèi)存地址。因此,當(dāng)ChangeReferenceType()方法更改StudentName時,它實際上是在更改std1對象的StudentName,因為std1和std2都指向內(nèi)存中的同一地址。
引用類型變量的默認(rèn)值null是未初始化時。 Null表示不引用任何對象。
值類型變量不能為null,因為它保存值而不是內(nèi)存地址。C#2.0引入了可為空的類型,使用它可以為值類型變量分配null或聲明值類型變量而無需為其分配值。