19

该代码非常不言自明。我预计当我创建a1并且b1我正在创建两个包含相同文本的不同字符串实例时。所以我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
4

3 回答 3

20

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

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

于 2012-05-28T04:48:33.167 回答
8

编译器已优化为 if 字符串文字与“==”运算符相等,而不需要创建新实例并且都引用同一个实例......所以,这就是为什么您的问题的第一部分回答 True 的原因。

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

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

这显示“True”,然后显示“False”,因为字符串的内容是等价的,但是 a 和 b 不引用同一个字符串实例。

+ 运算符连接字符串:

string a = "good " + "morning";

这将创建一个包含“早上好”的字符串对象。

Strings are immutable--the contents of a string object cannot be changed after the object is created, although the syntax makes it appear as if you can do this. For example, when you write this code, the compiler actually creates a new string object to hold the new sequence of characters, and that new object is assigned to b. The string "h" is then eligible for garbage collection.

string b = "h";
b += "ello";

for more reference check this on msdn and this

于 2012-05-28T04:58:00.310 回答
2

编译器优化。就那么简单。

于 2012-05-28T04:45:29.223 回答