理解C# String類(lèi)型:特殊的引用類(lèi)型
有關(guān)C# String類(lèi)型究竟是值類(lèi)型還是引用類(lèi)型,在很多C#學(xué)習(xí)者中都或多或少造成過(guò)困惑。好比下面這個(gè)例子:
- class Class1
- {
- static void StrChange(string str)
- {
- str = "hellow";
- }
- static void Main()
- {
- string str = "123";//申明一個(gè)字符串
- StrChange(str);//調(diào)用方法
- Console.WriteLine(str);//輸出字符串
- }
- }
輸出的結(jié)果是 "123" 。
那么,string 到底是值類(lèi)型還是引用類(lèi)型?有人會(huì)說(shuō),如果是值類(lèi)型,結(jié)果倒還說(shuō)的過(guò)去.但是string 的定義不是應(yīng)該是引用類(lèi)型么?如果是引用類(lèi)型的話(huà).輸出的結(jié)果難度不應(yīng)該是: "hellow"么?
解答這個(gè)問(wèn)題的關(guān)鍵在于,C# string類(lèi)型是特殊的引用類(lèi)型,它的實(shí)例是只讀的。這個(gè)地方要搞清楚語(yǔ)法和實(shí)現(xiàn)的區(qū)別 。在C#的語(yǔ)法中,
◆static void StrChange(string str) 是值傳遞
◆static void StrChange(ref string str) 是引用傳遞
但在實(shí)現(xiàn)上,static void StrChange(string str) 這種值傳遞,在函數(shù)體內(nèi)對(duì)str進(jìn)行修改之前,與函數(shù)外部的變量指向同一塊內(nèi)存,是“引用”傳遞,但在函數(shù)體內(nèi)對(duì)str修改后,就會(huì)觸發(fā)對(duì)該str重新分配一塊內(nèi)存。
所以說(shuō),String 是引用類(lèi)型,不過(guò)是不可變的。對(duì)字符串做一些操作(比如大小寫(xiě)的轉(zhuǎn)換、+=), 實(shí)際上是重新創(chuàng)建了一個(gè)字符串。這也是為什么在做大量字符串拼接的時(shí)候要使用StringBuilder 而不用+=。
有關(guān)C# String類(lèi)型做為引用類(lèi)型的特別之處,可以參看下例的示例及注釋:
- private void button2_Click(object sender, EventArgs e)
- {
- string str="aaa";
- string str1 = str;
- str = "bbb";//注釋掉此名就"yes",否則"no".這就說(shuō)明str重新賦值的時(shí)候,
- //其實(shí)是重新創(chuàng)建了一個(gè)名為str的字符串(內(nèi)存中指向的位置是不同的),先前
- //的那個(gè)str你就再也看不到了.
- string str2 = str;
- if (object.ReferenceEquals( str1,str2))
- {
- MessageBox.Show("yes");
- }
- else
- {
- MessageBox.Show("no");
- }
- }
最后回到一開(kāi)始的那段代碼。如果想下面這樣編寫(xiě):
- class Class1
- {
- static string StrChange(string str)
- {
- str = "hellow";
- return str;
- }
- static void Main()
- {
- string str = "123";//申明一個(gè)字符串
- str=StrChange(str);//調(diào)用方法
- Console.WriteLine(str);//輸出字符串
- }
- }
這樣輸出的便是hellow了。
【編輯推薦】