ReferenceEquals使用字符串时出错
本文关键字:出错 字符串 ReferenceEquals | 更新日期: 2023-09-27 18:22:09
为什么在这种情况下对象的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
,因为它比较了我的对象的引用。
第一个例子有一个由两个变量引用的编译时常数"fg"
。由于这是一个编译时常数,所以两个变量引用一个对象。参考文献是相等的。
阅读字符串实习主题,了解有关此行为的更多信息。作为入门,请考虑:
例如,如果将同一个文字字符串分配给多个变量,则运行时会从实习生池中检索对该文字字符串的相同引用,并将其分配给每个变量。
http://msdn.microsoft.com/en-us/library/system.string.intern.aspx
在第二个例子中,只有一个是编译时常数,另一个是一些操作的结果。a
和d
没有引用同一个对象,因此从ReferenceEquals
得到错误的结果。
它在这两种情况下都表现正确。
a
和b
是同一个字符串对象的原因是编译器注意到您指定了两次相同的字符串,并重用了相同的字符串对象来初始化a
和b
。
这通常会发生在应用程序中的每个字符串常量中。
这是因为版本高于4.5的CLR程序集标记有属性System.Runtime.CompilerServices.CompilationRelaxations Attribute
,该属性定义了标志System.Runtime.CompilerServices. CompilationRelaxations.NoStringInterning
的值。实现此功能是为了提高性能。
如果在4.5以下的CLR版本中运行代码,变量a
和b
将引用堆中值为"0"的不同字符串对象;fg";并且CCD_ 16将给出结果"0";错误";。
由于CLR 4.5,CCD_ 17的比较将给出结果"0";真";,因为它是实习生"fg";将程序集上载到应用程序域时的字符串。这意味着a
和b
引用堆中的相同字符串。
由于引用了相同的文字("fg"),所以两个字符串实际上都指向同一个东西。请看一下这篇文章:http://csharpindepth.com/Articles/General/Strings.aspx("实习"一段)。
谨致问候,Piotr
根据这篇文章,这与所谓的实习有关。在您的情况下,a和b是指向同一实例的两个变量,这就是ReferenceEquals返回true的原因。