9

为什么在这种情况ReferenceEquals下对象的方法表现不同?

string a= "fg";
string b= "fg";
Console.WriteLine(object.ReferenceEquals(a, b));

所以在这种情况下,它会得到一个结果true。以防万一,它比较我的字符串的值而不是引用。但是当我写这样的东西时:

StringBuilder c = new StringBuilder("fg");
string d = c.ToString();
Console.WriteLine(object.ReferenceEquals(a, d));

在这种情况下,它工作正常,结果是false,因为它比较了我的对象的引用。

4

5 回答 5

17

"fg"第一个示例有一个由两个变量引用的编译时常量。由于这是一个编译时常量,因此这两个变量引用了一个对象。引用是相等的。

阅读字符串实习主题以了解有关此行为的更多信息。作为初学者,请考虑:

例如,如果您将相同的文字字符串分配给多个变量,则运行时会从实习池中检索对文字字符串的相同引用并将其分配给每个变量。

http://msdn.microsoft.com/en-us/library/system.string.intern.aspx

在第二个例子中,只有一个是编译时间常数,另一个是一些操作的结果。a并且d不要引用同一个对象,因此您会从ReferenceEquals.

于 2012-02-02T12:54:19.017 回答
3

它在这两种情况下都表现正确。

a和是同一个字符串对象的原因b是因为编译器注意到您指定了两次相同的字符串,并重用了相同的字符串对象来初始化ab

这通常会发生在应用程序中的每个字符串常量上。

于 2012-02-02T12:54:55.550 回答
0

由于您引用相同的文字(“fg”),因此您的两个字符串实际上都指向同一事物。请看这篇文章:http ://csharpindepth.com/Articles/General/Strings.aspx (“实习”段)。

问候, 彼得

于 2012-02-02T12:57:14.490 回答
0

根据这篇文章,它与所谓的实习有关。a 和 b 在您的情况下是两个变量指向同一个实例,这就是 ReferenceEquals 返回 true 的原因。

于 2012-02-02T12:57:48.877 回答
0

这是因为 4.5 以上版本的 CLR 程序集都标有System.Runtime.CompilerServices.CompilationRelaxations Attribute定义标志值的属性System.Runtime.CompilerServices. CompilationRelaxations.NoStringInterning。这是为了提高性能而实现的。

如果在 4.5 以下的 CLR 版本中运行您的代码,变量ab将引用堆中值为“fg”的不同字符串对象,object.ReferenceEquals(a, b)并将给出结果“False”。

由于 CLR 4.5 的比较object.ReferenceEquals(a, b)将给出结果“True”,因为它在将程序集上传到应用程序域时实习“fg”字符串。这意味着对堆中相同字符串的引用ab

于 2020-12-26T20:24:56.360 回答