我刚刚在MS Visual Studio文档中看到了这一点,粗体部分对我没有意义.这是错的还是我不理解它?如果你运行它,b似乎保持"你好"(正如我所料)而不是"h".
字符串是不可变的 - 在创建对象后,字符串对象的内容无法更改,尽管语法使其看起来好像可以执行此操作.例如,当您编写此代码时,编译器实际上会创建一个新的字符串对象来保存新的字符序列,而变量b继续保持"h".
string b ="h";
b + ="ello";
您已经一步完成了添加和分配.字符串是不可变的,但也是引用类型.
string b = "h"; b = b + "ello";
我们可以这样看一下伪内存:
string b = "h"; // b := 0x00001000 ["h"] string tmp1 = "ello"; // tmp1 := 0x00002000 ["ello"] string tmp2 = b + tmp1; // tmp2 := 0x00003000 ["hello"] string b = tmp2; // b := 0x00003000 ["hello"]
我不完全确定你在哪里获得该文本,因为当我阅读我找到的字符串类的文档时(不是我认为"h"实际上是垃圾收集):
字符串是不可变的 - 在创建对象后,字符串对象的内容无法更改,尽管语法使其看起来好像可以执行此操作.例如,当您编写此代码时,编译器实际上会创建一个新的字符串对象来保存新的字符序列,并将该新对象分配给b.然后字符串"h"有资格进行垃圾回收.
@Jon Skeet提出"h"永远不会因为字符串实习而被垃圾收集,我同意他,但更多的是C#Standard同意他,否则§2.4.4.5字符串文字中的以下内容不可能是真的:
每个字符串文字不一定会产生新的字符串实例.当根据字符串相等运算符(第7.9.7节)等效的两个或多个字符串文字出现在同一程序中时,这些字符串文字引用相同的字符串实例.
人们似乎并没有理解这个问题.没有人认为字符串对象不是不可变的.争论点是他粗犷的:
并且变量b继续保持"h"
我同意OP同意这部分文件在两个方面是不正确的:
(1)从直观的意义上说,如果你在他的两个样本行之后打印(b)(或者用这种语言正确的陈述),你将得到"你好"的结果.
(2)在严格意义上说,变量b不持有 "H","你好",或者任何字符串值.它包含对字符串对象的引用.
变量b的内容确实因赋值而改变 - 它从一个点变为字符串对象"h"变为一个指向字符串对象"hello"的指针.
当他们说"持有"他们真正的意思是"指向".并且他们错了,在任务之后b不再指向"h".
我认为他们真正想要的例子是:
string a = "h"; string b = a; b += "ello";
关键是,我相信,仍然会指向"h"; 即,对b的赋值不会修改它指向的对象,它会创建一个新对象并将b更改为指向它.
(我实际上并没有写C#,但这是我的理解.)