首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >我需要在引用类型上重写GetHashCode()吗?

我需要在引用类型上重写GetHashCode()吗?
EN

Stack Overflow用户
提问于 2009-04-20 18:15:39
回答 2查看 3.7K关注 0票数 22

我在StackOverflow上读到了大多数关于GetHashCode的问题。但我仍然不确定是否必须在引用类型上重写GetHashCode。在另一个问题中,我从某人的答案中获得了以下内容:

Object.GetHashCode()使用System.Object类中的内部字段来生成散列值。创建每个对象时,都会为其指定一个唯一的对象键,并将其存储为整数。这些键从1开始,并在每次创建任何类型的新对象时递增。

如果这在.NET Framework3.5中仍然是真的(有人能确认一下吗?),那么我看到的引用类型的默认实现的唯一问题是散列代码的分布会很差。

我会把我的问题分成几部分:

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

b)我有引用类型,因为它们有唯一标识它们的字段,所以很容易做到,但是如果引用类型的所有成员都是引用类型,那该怎么办?我应该在那里做什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-04-20 18:26:46

如果要覆盖GetHashCode(),则只需在引用类型上覆盖Object.Equals()。

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

但是,如果您重写Equals(),则不能保证此行为。如果两个对象相等(根据Equals()),您需要保证它们具有与GetHashCode相同的散列代码,因此您应该覆盖它。

票数 20
EN

Stack Overflow用户

发布于 2009-04-20 18:36:16

我刚刚做了一个样本测试,我不明白它是如何从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

实际上,使用Reflector,我只能看到:

internal static extern int InternalGetHashCode(object obj);

因此,它到底是如何发生的对我来说是一个谜(可能有一种模式,但我不打算在这一点上深入挖掘--也许是某种“伪随机数”algorithm?)。CLR团队的人可以回答这个问题。

至于其他问题,里德实际上比我先一步回答:GetHashCodeEquals。为了以防万一,MSDN page用更多血淋淋的细节来描述它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/769467

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档