我理解字符串是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告诉我,我已经猜到了字符串"你好"与世界"联系在一起形成一个新的字符串。但这是否意味着这条线的实际作用是:
a
。 或者我在这里完全错了?我真的很想知道幕后发生了什么""或者说.. ..
答案 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
,因此尚未收集垃圾。