是否需要对引用类型重写GetHashCode()?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (19)

如果在.NET Framework 3.5中仍然如此(有人可以确认吗?),那么我在默认的引用类型实现中遇到的唯一问题是散列代码的分布很差。

我会打破我的问题:

a)因此,它建议覆盖GetHashCode,如果它在a中使用Dictionary或者默认实现执行得很好吗?

b)我有参考类型,它很容易做到,因为它们具有唯一标识它们的字段,但是那些参考类型也是如此,其中所有成员都是参考类型。我应该在那里做什么?

提问于
用户回答回答于

如果重写Object.Equals(),则只需在引用类型上重写GetHashCode()。

原因很简单 - 通常,2个引用总是不同的(a.Equals(b)== false,除非它们是同一个对象)。在这种情况下,GetHashCode()的默认实现将提供2个不同的散列,所以一切都很好。

但是,如果你覆盖Equals(),则无法保证此行为。如果两个对象相等(按照Equals()),则需要保证它们与GetHashCode具有相同的哈希码,因此你应该重写它。

用户回答回答于

我只是做了一个样本测试,我没有看到它是如何从1开始并获得增量。

for (int i = 0; i < 16; i++)
{
    object obj = new object();
    Console.Write(obj.GetHashCode() + " ");
}

有了这些结果:

45653674 41149443 39785641 45523402 35287174 44419000 52697953 22597652 
10261382 59109011 42659827 40644060 17043416 28756230 18961937 47980820

事实上,使用反射器,我只能看到这一点:

internal static extern int InternalGetHashCode(object obj);

所以对我来说真的是一种莫名其妙(可能有一种模式,但我不打算在这一点上深入探讨 - 也许某种“伪随机数” 算法?)。来自CLR团队的人可以回答这个问题。

扫码关注云+社区