字符串的修改

时间:2014-04-15 19:18:13

标签: c# string immutability

我理解字符串是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告诉我,我已经猜到了字符串"你好"与世界"联系在一起形成一个新的字符串。但这是否意味着这条线的实际作用是:

  1. 使用值" world"创建一个字符串对象的新实例。
  2. 读取我们的第一个字符串对象的值"你好"然后用" world"将该值连接起来。形成第三个字符串。
  3. 将上述字符串的引用返回a
  4. " world"字符串实例现在是孤立的并标记为收集?
  5. 或者我在这里完全错了?我真的很想知道幕后发生了什么""或者说.. ..

4 个答案:

答案 0 :(得分:1)

是的,a += "world";确实做了你不解的事,相当于a = a + "world";

这是+=严格只是语法糖的情况。还是,谁不喜欢一些糖果?

答案 1 :(得分:1)

当您编写a += "world"时正如您正在编写a = a + "world",它实际上是根据字符串a"world"的串联创建一个新字符串,然后分配结果到a

答案 2 :(得分:1)

因为字符串是不可变的,所以对应于你的程序是:

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

因为字符串是不可变的,所以基本上包含new运算符。

如果您感兴趣,内部字符串将存储为字符数组(see here)。它们实际上存储在堆上,这就是为什么仔细使用字符串很重要(堆内存不是无限制的)。我还在这里找到了其他相关的堆栈问题:How are String and Char types stored in memory in .NET?

答案 3 :(得分:0)

执行a+="World"时,会创建一个值为a + "world"的新字符串。由于hello仍在使用b,因此尚未收集垃圾。