StringComparer.InvariantCultureIgnoreCase Equals vs GetHashCode不赞成相等的对象

时间:2019-01-17 20:02:21

标签: c# .net

StringComparer.InvariantCultureIgnoreCase Equals对于“” vs“ \ 0”返回true,但是GetHashCode返回两个字符串的不同值。这是错误吗?

var sc = StringComparer.InvariantCultureIgnoreCase;
string s1 = "";
string s2 = "\0";
Console.WriteLine( sc.Equals(s1, s2)  );
Console.WriteLine( sc.GetHashCode(s1) );
Console.WriteLine( sc.GetHashCode(s2) );

返回

True
0
-1644535362

我认为GetHashCode应该为“相等”字符串返回相同的值,所以这是一个错误吗?

1 个答案:

答案 0 :(得分:-3)

这2个字符串不是按位相等的。它们是2种不同的长度。因此,哈希码算法在这里是合理的。

字符串比较算法在进行比较时必须忽略\0。我looked into the source:它正在执行某种加/减比较算法,以找出是否不同。

GetHashCode仅表示值可以相等,不一定相同。相反的情况并不总是正确的,您可以覆盖==运算符或.Equals的任何类型,并在哈希码不一致的情况下产生true

这里是GetHashCode。看起来好像是在使用原始字节进行计算。

您可能偶然发现了.NET库中一个不起眼的错误,但是我猜测这是一个边缘情况。

然后再次-您正在使用字符串比较器。不是string.Equals方法或string.GetHashCode。请注意,Console.WriteLine("\0".Equals(""));产生false

如果您希望一个字符串比较器能够达成共识,我相信StringComparer.OrdinalIgnoreCase可以解决问题,因为它会分别查看每个字符,而不是根据值进行排序。 看起来两者都只是漏斗到了相同的字符比较方法。