String類型直接繼承自Object,所以它是一個要new出來的引用類型,即線程的堆棧上不會駐留有任何字串。
(所有的實值型別都繼承自System.ValueType。值得指出的是System.ValueType卻是一個
參考型別)
代碼一:
string str1 = "string"; string str2 = "stri"+"ng"; Console.WriteLine(string.ReferenceEquals(str1, str2));
既然String類型是參考型別,那麼代碼一輸出的應該是False,然而事實上代碼一輸出時的是True。
這是因為當CLR初始化時,它會建立
一個內部的散列表,Key為字串,Value為指向託管堆中字串對象的引用。
但是,動態建立的字串不會去查詢散列表,而是直接在託管堆中建立新的String對象。string str3 = "system." + str1;
當構造str1時,先會去散列表中查詢是否存在”string”字串,
如果不存在那麼會在託管堆(heap)中構造一個新的String對象,然後將”string”字串和指向該對象的引用添加到散列表中,當構造str2時,由於散列表中存在Key為”string”的引用,於是將Value值賦值給str2,那麼str1和str2引用的是同一個String對象,代碼一自然就返回
True了
代碼二:
static void Main(string[] args) { string str = "string"; Change(str); Console.WriteLine(str); }
static void Change(string str) { str = "Changed"; }
方法傳遞的參數是原內容的拷貝,其過程:
語句str=”Changed”之前
語句str=”Changed”之後
這樣可以看到原來String對象並未改變,str=”Changed”只是建立一個新的String對象(其它參考型別是改變記憶體位址1指向的值),因此這個方法的參數需要加上ref或者out修飾符。
這裡也可以得出字串具有恒等性,也就是說一個字串一旦被建立,我們就不能再將其變長、
變短、或者改變其中的任何字元。
代碼三:
string str1 = "string"; string str2 = "system." + "string"; string str3 = "system." + str1; string str4 = "system.string";
Console.WriteLine(string.Equals(str2, str3)); True
Console.WriteLine(string.ReferenceEquals(str2, str3)); False
Console.WriteLine(string.Equals(str4, str2)); True
Console.WriteLine(string.ReferenceEquals(str2, str4)); True
根據代碼一和二的分析,代碼三的輸出結果為:True True True True,然而事實卻不是這樣,正確的結果為:True False
True True。這是因為動態建立的字串不會去查詢散列表,而是直接在託管堆中建立新的String對象,如語句string str3 =
“syetem.”+str1,因此用string.ReferenceEquals來比較str2和str3會返回False,而用
string.ReferenceEquals來比較str2和str4會返回True。當然可以將str3字串手動加入到散列表中,並返回引
用:str3 =
string.Intern(str3),這樣用string.ReferenceEquals來比較str2和str3會返回True,至於
string.Equals都返回True的原因是String重寫了Equals方法,內部會先檢查兩個引用是否指向同一個對象,如果是返回True,
不是則再比較各個字元。
引用:http://www.diybl.com/course/4_webprogram/asp.net/netjs/20091107/181566.html
@, 克服了逸出字元串帶來的閱讀障礙。
Double.Parse, TryParse(str, out num); Convert.ToDouble, 異常處理方式不同。
按引用傳遞,ref參數傳遞之前必須初始化,out沒要求。
sizeof擷取實值型別大小,不適用於參考型別。 實值型別繼承自ValueType, which inherits Object, but it overrides Equals方法,按值比較,instead of 引用地址。String也重載了Equals方法,比較值大小。