如果字符串在c#中是不可变的,我怎么会这样做?

Rus*_*ova 8 c#

我今天读到,在c#字符串是不可变的,就像一旦创建它们不能被改变,那么下面的代码如何工作

string str="a";
str +="b";
str +="c";
str +="d";
str +="e";

console.write(str) //output: abcde
Run Code Online (Sandbox Code Playgroud)

怎么变量的值变了?

Ray*_*oal 14

字符串对象是不可变的,但可以重新分配变量.

您创建了单独的对象

a
ab
abc
abcd
abcde
Run Code Online (Sandbox Code Playgroud)

这些不可变字符串中的每一个又被分配给变量str.

您无法更改字符串中的内容(字符内).

改变变量完全是另一回事.

  • @nekno我拒绝接受"最好使用StringBuilder"这一概念.虽然可以推导出StringBuilder*显着更快*的情况(例如,对于模板生成,它非常适合),但它本身并不"更有效"或"更快"或"更好".我通常使用`+ =`因为1)*我通常更清楚*和; 2)*没关系.* (5认同)

小智 7

这是很容易证明后并没有发生变异的String对象为认为:

string a = "a";
string b = a;
Console.WriteLine(object.ReferenceEquals(a, b)); // true
Console.WriteLine(a); // a
Console.WriteLine(b); // a
b += "b";
Console.WriteLine(object.ReferenceEquals(a, b)); // false
Console.WriteLine(a); // a
Console.WriteLine(b); // ab
Run Code Online (Sandbox Code Playgroud)

这是因为x += y操作员相当于x = x + y,但输入较少.

快乐的编码.

  • +1用于突出显示“ ReferenceEquals”。真好 (2认同)

Joh*_*nFx 5

使用反射器查看ILM代码,您将确切了解正在发生的情况。尽管您的代码在逻辑上将新内容附加到字符串的末尾,但在后台编译器仍在创建ILM代码,该代码正在为每个分配创建新的字符串。

如果在单个语句中连接文字字符串,则图片会变得更加混乱:

str = "a" + "b" + "c" ...
Run Code Online (Sandbox Code Playgroud)

在这种情况下,编译器通常足够聪明,不会创建所有多余的字符串(因此适用于垃圾回收器,并将其转换为等效于ILM的代码:

str = "abc"
Run Code Online (Sandbox Code Playgroud)

也就是说,像这样在单独的行上执行此操作可能不会触发该优化。