.net中String是參考型別還是實值型別 以及 C#深層拷貝淺層拷貝

來源:互聯網
上載者:User

標籤:style   blog   http   color   os   ar   for   sp   strong   

http://www.cnblogs.com/yank/archive/2011/10/24/2204145.html

http://www.cnblogs.com/zwq194/archive/2012/08/06/2625403.html

 

關於String為實值型別還是參考型別的討論一直沒有平息,最近一直在研究效能方面的問題,今天再次將此問題進行一次明確。希望能給大家帶來點協助。 如果有錯誤請指出。

來看下面例子:

            //實值型別            int a = 1;            int b = a;            a = 2;            Console.WriteLine("a is {0},b is {1}", a, b);            //字串            string str1 = "ab";            string str2 = str1;            str1 = "abc";            Console.WriteLine("str1 is {0},str2 is {1}", str1, str2);            Console.Read();    

根據上面的例子:你覺得輸出結果應該是什嗎?

 

輸出結果:

            //結果:            //a is 2,b is 1            //str1 is abc,str2 is ab

str2依然是ab,並沒有隨str1的改變而改變。

如果string是參考型別,按理Str1和Str指標都指向同一記憶體位址,如果Str的內容發生改變,Str1應該也會相應變化。

此例子,看著string更像是實值型別。 

但是MSDN卻說String是參考型別,

參考型別包括:  String

所有數組,即使其元素是實值型別

類類型,如 Form

委託

可參考:http://msdn.microsoft.com/zh-cn/library/t63sy5hs(VS.80).aspx

查看具體引用是否相同

如果Net能夠查看記憶體位址就容易了,但不允許,只能通過間接方法來實現,看下面:

        static void TestRefAddress()        {            String str1 = "abc";            String str2 = "abc";            int a = 1;            int b = 1;            StringBuilder strb1 = new StringBuilder("abc");            StringBuilder strb2 = new StringBuilder("abc");            Console.WriteLine("Reference equal for string: " + Object.ReferenceEquals(str1, str2)); //結果true            Console.WriteLine("Reference equal for int: " + Object.ReferenceEquals(a, b)); //結果false            Console.WriteLine("Reference equal for StringBuilder: " + Object.ReferenceEquals(strb1, strb2)); //結果false            Console.WriteLine("Value equal for string: " + str1.Equals(str2)); //結果true,類似於實值型別            Console.Read();        }

結果為何出現如此情況,分析如下:

    Console.WriteLine("Reference equal for string: " + Object.ReferenceEquals(str1, str2)); //結果true,不同對象,但引用地址相同    Console.WriteLine("Reference equal for int: " + Object.ReferenceEquals(a, b)); //結果false,實值型別裝箱操作造成    Console.WriteLine("Reference equal for StringBuilder: " + Object.ReferenceEquals(strb1, strb2)); //結果false,不同對象,引用地址不同    Console.WriteLine("Value equal for string: " + str1.Equals(str2)); //結果true,類似於實值型別

由第一條結果,可以判定不同的String的,相同的值,其引用地址相同,再由第四條結果,str1.Equals(str2),兩者結合,可得出結論,兩個String,如果賦值為同一個值,在記憶體中只有一個字串存在,兩個引用的地址相同。由此引出String的不變性。

String的不變性

string最為顯著的一個特點就是它具有恒定不變性:我們一旦建立了一個string,在managed heap 上為他分配了一塊連續的記憶體空間,我們將不能以任何方式對這個string進行修改使之變長、變短、改變格式。所有對這個string進行各項操作(比如調用ToUpper獲得大寫格式的string)而返回的string,實際上另一個重新建立的string,其本身並不會產生任何變化。 string   對象稱為不可變的(唯讀),因為一旦建立了該對象,就不能修改該對象的值。有的時候看來似乎修改了,實際是string經過了特殊處理,每次改變值時都會建立一個新的string對象,變數會指向這個新的對象,而原來的還是指向原來的對象,所以不會改變。這也是string效率低下的原因。

String的不變,並非說string不能改變,而是其值不能改變。

在例子中str1="ab",這時在記憶體中就將“ab”存下來,如果再建立字串對象,其值也等於“ab”,str2="ab",則並非再重新分配記憶體空間,而是將之前儲存的“ab”的地址賦給str2的引用,這就能印證例子2中的結果。而當str1="abc"其值發生改變時,這時檢查記憶體,發現不存在此字串,則重新分配記憶體空間,儲存“abc”,並將其地址賦給str1,而str2依然指向“ab”的地址。可以印證例子1中的結果。

 

結論:

String是參考型別,只是編譯器對其做了特殊處理。

 

關於討論:http://social.msdn.microsoft.com/Forums/zh-CN/visualcshartzhchs/thread/ce580186-86d9-45f7-b5ff-20302caf1324

 

 

關於C#深層拷貝淺層拷貝:

  C#中有兩種類型變數,一種是實值型別變數,一種是參考型別變數。【淺拷貝就是表面上拷貝了地址;深拷貝就是拷貝了內容 】 對於實值型別變數,copy是屬於全盤複製; 而對於參考型別變數,一般的copy只是淺copy,相當於只傳遞一個引用指標一樣。 因此對於參考型別變數進行真正copy的時候,也是最費事的。

  淺拷貝 只是複製本身,它包含的對象只是複製引用,其中包含的對象就直接拿來用了,這樣產生的問題就是:如果一個被修改了,另一個也跟著變。是這樣的,但是除了string類型外,string類型,本來屬於參考型別,因此在進行複製的時候,採用的是淺拷貝,但當發生變化的時候,系統會自動產生進行深copy。 對象的欄位如果是實值型別,那麼無論是淺拷貝還是深拷貝都是原樣複製。

  深拷貝 不僅要複製本身,還要複製他所包含對象。對象的欄位如果是參考型別,那麼淺拷貝是複製引用,深拷貝是複製引用的對象。

.net中String是參考型別還是實值型別 以及 C#深層拷貝淺層拷貝

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.