.Net框架程序設計(修訂版)中有這樣一段描述:
String類型直接繼承自Object,這使得它成為一個引用類型,也就是說線程上的堆棧上不會駐留有任何字符串。
string類型(引用類型)
名稱 |
CTS類型 |
說明 |
string |
System.String |
Unicode字符串 |
string str1 = "hello "; string str2 = "world ";
這是一個值類型的賦值,但string是一個引用類型。String被分配在堆上,而不是棧上。因此,當把一個字符串變量賦給另一個字符串時,會得到對內存中同一個字符串的兩個引用。但是,string與引用類型在常見的操作上有一些區別。例如字符串是不可改變的。修改其中一個字符串,就會創建一個全新的string對象,而另一個字符串不會發生任何變化。
using System; class StringExample { public static int Main() { string s1 ="aaaa"; string s2 = s1; Console.WriteLine("s1:" + s1); Console.WriteLine("s2:" + s2); s1 = "bbbb"; Console.WriteLine("s1:" + s1); Console.WriteLine("s2:" + s2); return 0; } }
輸出結果:
s1: aaaa
s2: aaaa
s1: bbbb
s2: aaaa
改變s1的值對s2沒有影響,這與引用類型的操作相反,當用"aaaa"初始化s1時,就在堆上分配了一個新的string對象。在初始化s2時,引用也指向這個對象,所以s2的值也是"aaaa",但是當改變s1的值時,並不會替換原來的值,堆上會為新值分配一個新的string對象,s2扔指向原來的對象,所以它的值沒有變。這實際上是運算符重載的結果。