簡體   English   中英

字符串的修改

[英]Modification of strings

我知道字符串是C#中的不可變引用類型。 但我有一個更具體的問題。

string a = "hello ";
string b = a;
a += "world";
Console.WriteLine(b);

上面的代碼將生成輸出hello 我意識到這是因為字符串是不可變的,所以一旦我們創建了一個值為“hello”的字符串實例,它就無法修改。 但我想知道,當我們做a += "world"時會發生什么? 看着IL似乎不幸地給了我整個故事(或者可能是我太新手無法看到更大的圖片)

IL_0001:  ldstr       "hello "
IL_0006:  stloc.0     // a
IL_0007:  ldloc.0     // a
IL_0008:  stloc.1     // b
IL_0009:  ldloc.0     // a
IL_000A:  ldstr       "world"
IL_000F:  call        System.String.Concat
IL_0014:  stloc.0     // a
IL_0015:  ldloc.0     // a
IL_0016:  call        System.Console.WriteLine

IL告訴我,我已經猜到字符串“hello”與“world”連接成一個新的字符串。 但這是否意味着這條線實際上做的是:

  1. 使用值“world”創建字符串對象的新實例。
  2. 讀取我們的第一個字符串對象“hello”的值,然后將該值與“world”連接以形成第三個字符串。
  3. 將上述字符串的引用返回給a
  4. “world”字符串實例現在是孤立的並標記為收集?

或者我在這里完全錯了? 我真的想知道“幕后”發生了什么,或者說......

是的, a += "world"; 真的做了你困惑的事情,相當於a = a + "world";

這是+=僅僅是語法糖的情況。 還是,誰不喜歡一些糖果?

當你寫a += "world"就像你正在寫a = a + "world" ,它實際上是從字符串a"world"的串聯中創建一個新字符串,然后將結果分配給a

因為字符串是不可變的,所以一個等價於你的程序是:

string a = "hello ";
string b = a;
a = new string(a + "world");

因為字符串是不可變的,所以基本上包含了new運算符。

如果您感興趣,內部字符串將存儲為字符數組( 請參閱此處 )。 它們實際上存儲在堆上,這就是為什么仔細使用字符串很重要(堆內存不是無限制的)。 我還在這里找到了另一個相關的堆棧問題: String和Char類型如何存儲在.NET的內存中?

當你執行a+="World" ,它會創建一個值為a + "world"的新字符串。 既然hello仍然被b ,它還沒有被垃圾收集。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM