两个不同的"字符串"是同一个对象实例?

jb.*_*jb. 19 c# string equality reference

代码非常自我解释.我预计当我创建a1b1创建两个包含相同文本的不同字符串实例时.所以我a1 == b1认为这是真的但是object.ReferenceEquals(a1,b1)会是假的,但事实并非如此.为什么?

//make two seemingly different string instances
string a1 = "test";
string b1 = "test";         
Console.WriteLine(object.ReferenceEquals(a1, b1)); // prints True. why?

//explicitly "recreating" b2
string a2 = "test";
string b2 = "tes";
b2 += "t";    
Console.WriteLine(object.ReferenceEquals(a2, b2)); // prints False

//explicitly using new string constructor
string a3 = new string("test".ToCharArray());
string b3 = new string("test".ToCharArray());    
Console.WriteLine(object.ReferenceEquals(a3, b3)); // prints False
Run Code Online (Sandbox Code Playgroud)

Gre*_*ill 20

文字字符串对象由编译器合并为单个实例.这实际上是规范要求的:

每个字符串文字不一定会产生新的字符串实例.当两个或多个根据字符串相等运算符(第7.9.7节)等效的字符串文字出现在同一个程序集中时,这些字符串文字引用相同的字符串实例.


Tal*_*lha 8

如果字符串文字与"=="操作符等于比它并不需要创建一个新的实例,都指向同一个实例编译器优化到了......所以,这就是为什么你的问题的第一部分回答了真.

虽然string是引用类型,但是定义了相等运算符(==和!=)来比较字符串对象的值,而不是引用.这使得对字符串相等性的测试更加直观.例如:

string a = "hello";
string b = "h";
// Append to contents of 'b'
b += "ello";
Console.WriteLine(a == b);
Console.WriteLine((object)a == (object)b);
Run Code Online (Sandbox Code Playgroud)

这显示"True"然后"False",因为字符串的内容是等效的,但a和b不引用相同的字符串实例.

+运算符连接字符串:

string a = "good " + "morning";
Run Code Online (Sandbox Code Playgroud)

这将创建一个包含"早上好"的字符串对象.

字符串是不可变的 - 在创建对象后,字符串对象的内容无法更改,尽管语法使其看起来好像可以执行此操作.例如,当您编写此代码时,编译器实际上会创建一个新的字符串对象来保存新的字符序列,并将该新对象分配给b.然后字符串"h"有资格进行垃圾回收.

string b = "h";
b += "ello";
Run Code Online (Sandbox Code Playgroud)

有关更多参考,请在msdnthis上查看