MSDN 中明確指出 String 是引用類型而不是值類型,但 String 表面上用起來卻像是值類型,這又是什麼緣由呢?
首先從下面這個例子入手:html
//值類型
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();
輸出結果:python
//結果:
//a is 2,b is 1
//str1 is abc,str2 is ab
從運行結果能夠看出:str2 的值仍是 ab ,並無隨着 str1 值的改變而改變。若是string是引用類型,按理Str1和Str指針都指向同一內存地址,若是Str的內容發生改變,Str1應該也會相應變化。此例子,看着string更像是值類型。 可是MSDN卻說String是引用類型。究其緣由,是由於string對象是不可變的,包括長度和其中任何字符都是不能夠改變的。markdown
string 對象稱爲不可變的(只讀),由於一旦建立了該對象,就不能修改該對象的值。有的時候看來彷佛修改了,實際是string通過了特殊處理,每次改變值時都會創建一個新的string對象,變量會指向這個新的對象,而原來的仍是指向原來的對象,因此不會改變。這也是string效率低下的緣由。若是常常改變string的值則應該使用StringBuilder而不使用string。ui
在例子中str1=」ab」,這時在內存中就將「ab」存下來,若是再建立字符串對象,其值也等於「ab」,str2=」ab」,則並不是再從新分配內存空間,而是將以前保存的「ab」的地址賦給str2的引用,這就能印證例子2中的結果。而當str1=」abc」其值發生改變時,這時檢查內存,發現不存在此字符串,則從新分配內存空間,存儲「abc」,並將其地址賦給str1,而str2依然指向「ab」的地址。能夠印證例子中的結果。spa
String是引用類型,只是編譯器對其作了特殊處理。指針