C# 中的引用類型和值類型

C#中所有的類都是引用類型,大部分基本類型是值類型,基本類型中也有一些是引用類型,包括string、object。數組也是隱式的引用類型。

那麼什麼是值類型,什麼是引用類型?主要區別包括:1在內存中的位置不同,2使用方式不同。

1 內存中的位置不同

值類型是在系統的堆棧中分配空間,引用類型是在系統的堆中分配空間。

2 使用方式

public class MyClass
{
    public int val;
};
public struct MyStruct
{
    public int val;
};

...
static void Main(string[] args)
{
    MyClass c1 = new MyClass();
    MyClass c2 = c1;
    MyStruct s1 = new MyStruct;
    MyStruct s2 = s1;
    c1.val = 10;
    c2.val = 20;
    s1.val = 30;
    s2.val = 40;
    Console.WriteLine("{0} {1} {2} {3}", c1.val, c2.val, s1.val, s2.val);
}
上面代碼的輸出是20,20,30,40。

也就是,c1,c2是指向同一個類,對任何一個變量的修改都會影響到另外一個。

這個操作和C++有着非常大的區別。

在C++中,這個操作調用的是類重載的賦值操作符。如果沒有自己定義,編譯器會爲每個類定義一個默認的賦值操作符。默認操作符的工作是簡單的把每個類成員複製給左值的每個對應的類成員。也就是說,它的前提是,賦值操作符的左值和右值是不同的對象的實體。在C++中,如果類的成員中沒有指針,那麼直接用編譯器提供的賦值操作符是安全的。

但在C#中,對於引用類型,賦值操作符就是把右值的引用複製給左值。那麼結果就是左值成了和右值一樣的引用。如果左值本來是另外一個對象的引用,那麼這個對象就沒丟棄,如果它的引用計數爲0,那麼就只能等待垃圾回收程序來回收它佔用的內存。

所以,如果函數的形參是一個引用類型,函數都會修改這個引用類型所指向的值,不管它有沒有用ref關鍵字。如果沒有用ref關鍵字修飾引用類型,函數可以修改該應用類型指向的值,但不會修改引用類型本身的指向!!!

另外,new後面的類型名稱似乎都必須加"()"。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章