在编写一个使用字节数组作为内部存储的不可变ByteArray
类时,我实现了IStructuralEquatable
接口。在我的实现中,我将计算哈希码的任务委托给了内部数组。在测试过程中,令我惊讶的是,我发现我的两个不同的数组具有相同的结构哈希码,也就是说它们从GetHashCode
返回了相同的值。要复现:
IStructuralEquatable array11 = new int[] { 1, 1 };
IStructuralEquatable array12 = new int[] { 1, 2 };
IStructuralEquatable array22 = new int[] { 2, 2 };
var comparer = EqualityComparer<int>.Default;
Console.WriteLine(array11.GetHashCode(comparer)); // 32
Console.WriteLine(array12.GetHashCode(comparer)); // 32
Console.WriteLine(array22.GetHashCode(comparer)); // 64
IStructuralEquatable
是一个相当新的且不为人知的接口,但我在某处读到它可以用于比较集合和数组的内容。我是错了吗?还是我的 .Net 出了问题?
请注意,我并不是在谈论 Object.GetHashCode
!
编辑:
所以,显然我错了,因为不相等的对象可能具有相等的哈希码。但是,GetHashCode
返回一组随机分布的值不是一个要求吗?经过更多测试,我发现任何两个具有相同第一个元素的数组具有相同的哈希值。我仍然认为这是奇怪的行为。
GetHashCode
调用类型的不同对象吗?在这种情况下,很容易看出答案是“是”。因此,GetHashCode
是一种压缩投影到较小集合的方式-必定存在重复项。 - codekaizenArray.IStructuralEquatable.GetHashCode
只使用最后8个元素来计算哈希码。 - Michael Graczyk