C#學習筆記:實值型別與參考型別(詳解)

來源:互聯網
上載者:User
這個問題應該是困擾任何一門語言初學者的問題,為此整理了網上的一些資料,希望能為大家解惑。

首先對於C#中的資料類型,只有兩種,不是實值型別就是參考型別。

實值型別:結構體(數實值型別,bool型,使用者定義的結構體),枚舉,可空類型

參考型別:數組,使用者定義的類、介面、委託,object,字串。

從表面的概念上看,實值型別是直接儲存其值,而參考型別儲存的是對值的引用。

從儲存在記憶體的位置來看,實值型別是儲存在堆棧(線程堆棧)上,而參考型別是儲存在託管堆上。

(事實上,對於新手來說,也沒有必要去細究堆棧和託管堆是什麼,只需要知道是記憶體中的兩塊不同的地區就可以了,但為了保持嚴謹的治學態度,我建議大家可以參考:http://www.cnblogs.com/axzxs2001/archive/2008/08/28/1279037.html

講這些內容還是比較晦澀的,下面通過一個樣本講解:

 1//參考型別SomeRef
 2
 3    class SomeRef
 4
 5  {
 6
 7        public Int32 x;
 8
 9    }
10
11    //實值型別SomeVal
12
13    struct SomeVal
14
15  {
16
17        public Int32 x;
18
19    }
20
21    static void ValueTypeDemo()
22
23  {
24
25        SomeRef r1 = new SomeRef();//在託管堆上分配
26
27        SomeVal v1 = new SomeVal();//在堆棧上分配
28
29        r1.x = 5;                  //提領指標
30
31        v1.x = 5;                  //在堆棧上實際修改
32
33        Console.WriteLine(r1.x);   //顯示5
34
35        Console.WriteLine(v1.x);   //顯示5
36
37 
38
39
40        //以上代碼為圖的左邊部分,以下代碼為右邊部分
41
42 
43
44
45        SomeRef r2 = r1;           //只複製引用()
46
47        SomeVal v2 = v1;           //在堆棧上分配並複製成員 
48
49        r1.x = 8;                  //修改r1.x和r2.x  
50        v1.x = 9;                  //只修改v1.x而不修改v2.x
51        Console.WriteLine(r1.x);   //8        
52        Console.WriteLine(r2.x);   //8        
53        Console.WriteLine(v1.x);   //9
54        Console.WriteLine(v2.x);   //5
55
56    }
57
58

事實上通過這個樣本,大家已經可以很清晰的區分實值型別與參考型別的一些區別了,尤其關於賦值的問題:實值型別賦值是通過值的複製來實現的,修改新的變數的值對原變數沒有影響,而參考型別的賦值實際上是賦予給對象的引用,修改任何一個的值實際上修改了其引用,所有指向這個引用的變數的值都會發生改變。

但有時候你會發現這樣的問題:

string s1 = "hello";
string s2 = s1;
Console.WriteLine(s1);    //hello
Console.WriteLine(s2);    //hello
s1="goodbye";
Console.WriteLine(s1);    //goodbye
Console.WriteLine(s2);    //hello

剛才我們也提到string類型屬於參考型別,又根據參考型別值的特點,這裡修改s1的值後,s2的值應該發生改變才對?
事實上這裡並不矛盾,原因在於當改變s1的值是,實際上新建立了一個string對象,s1引用這個新的string對象;s2仍然引用原來string對象。產生這種行為的原因是string對象是恒定的,也就是說,一旦一個string對象被建立,它的值就不能再修改,所以當改變一個字串變數的值的時候,僅僅是新建立了一個包含修改內容的新的string對象。這點大家要特別注意。

補充:

設計自己的類型時,是考慮使用實值型別還是參考型別,某些時候,實值型別比參考型別有更好的效能。以下幾種情況應該考慮使用實值型別:

(1)類型具有一個基元類型的行為,也就是這是一個非常簡單的類型,其中沒有成員會修改類型的任何欄位。

(2)類型不需要從其它任何類型繼承也不會派生出其它任何類型

(3)類型的執行個體較小,約為16位元組或更小 

(4)類型的執行個體較大,大於16位元組,但不作為方法傳遞,也不作為方法的傳回型別使用

參考文章:http://www.cnblogs.com/chenzehe/archive/2009/01/30/1381073.html
http://blog.csdn.net/canduecho/archive/2008/01/13/2042509.aspx

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.