是因为CLR的字符串池还是两个字符串的GetHashCode()方法返回相同的值?
string s1 = "xyz"; string s2 = "xyz"; Console.WriteLine(" s1 reference equals s2 : {0}", object.ReferenceEquals(s1, s2));
控制台写道:"s1引用等于s2:True"
我相信,这不是因为GetHashCode()为两个字符串实例返回相同的值.因为,我测试了自定义对象并重写了GetHasCode()方法,每次都返回一个常量.此对象的两个单独实例在引用中不相等.
请让我知道,幕后发生了什么.
谢谢123Developer
这听起来像字符串实习 - 一种只存储一个字符串副本的方法.它要求字符串是您正在处理的语言中的不可变类型,.Net满足它并使用字符串实习.
在字符串实习中,字符串"xyz"存储在实习池中,每当您在内部说"xyz"时,它就会引用池中的条目.这可以通过仅存储一次字符串来节省空间.因此,"xyz"=="xyz"的比较将被解释为[指向34576的指针] == [指向34576的指针],这是真的.
这绝对是由于字符串实习.在比较引用时,永远不会计算散列码object.ReferenceEquals
.
从C#规范,第2.4.4.5节:
每个字符串文字不一定会产生新的字符串实例.当根据字符串相等运算符(第7.9.7节)等效的两个或多个字符串文字出现在同一程序中时,这些字符串文字引用相同的字符串实例.
请注意,在这种情况下,字符串常量表达式计为文字,因此:
string x = "a" + "b"; string y = "ab";
它保证x
并且也y
引用相同的对象(即它们是相同的引用).
当规范顺便说出"程序"时,它实际上意味着"组装".不同程序集中相等字符串的行为取决于类似CompilationRelaxations.NoStringInterning
的东西以及精确的CLR实现和执行时间情况(例如,程序集是否为ngen'd).