我是否需要重写引用类型上的 GetHashCode() ?

发布于 2024-07-17 14:19:08 字数 606 浏览 4 评论 0原文

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

Object.GetHashCode() 使用内部 System.Object 类中的字段 生成哈希值。 每个对象 创建的对象被分配了一个唯一的对象 key,存储为整数,当它是 创建的。 这些键从 1 开始并且 每次增加一个新对象时都会增加 创建任何类型。

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

我将分解我的问题:

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

b) 我有引用类型,这很容易做到,因为它们具有唯一标识它们的字段,但是那些所有成员也是引用类型的引用类型又如何呢? 我应该在那里做什么?

I read most questions on StackOverflow with regards to GetHashCode. But I am still not sure whether I have to override GetHashCode on reference types. I picked up the following from someones answer in another question:

Object.GetHashCode() uses an internal
field in the System.Object class to
generate the hash value. Each object
created is assigned a unique object
key, stored as an integer,when it is
created. These keys start at 1 and
increment every time a new object of
any type gets created.

If this is still true in .NET Framework 3.5 (can someone please confirm?), then the only problem I see with the default implementations of reference types is that the hash code will have a poor distribution.

I'll break up my questions:

a) So it it recommended to override GetHashCode too if it is used in a Dictionary or does the default implementation perform just fine?

b) I have reference types where it would be easy to do since they have fields that identify them uniquely but what about those reference types where all members are also reference types. What should I do there?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

稚气少女 2024-07-24 14:19:08

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

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

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

You only need to override GetHashCode() on reference types if you override Object.Equals().

The reason for this is simple - normally, 2 references will always be distinct (a.Equals(b)==false, unless they're the same object). The default implementation of GetHashCode() will provide 2 distinct hashes in this case, so all is good.

If you override Equals(), though, this behavior is not guaranteed. If two objects are equal (as per Equals()), you need to guarantee that they'll have the same hash code with GetHashCode, so you should override it.

请远离我 2024-07-24 14:19:08

我刚刚做了一个示例测试,我没有看到它如何从 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);

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

至于其他问题,Reed 实际上先于我:GetHashCodeEquals。 MSDN 页面 描述了它,并提供了更多血淋淋的细节, 万一。

I just did a sample test, and I do not see how it starts at 1 and gets increment.

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

with these results:

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

In fact, using Reflector, I only could see this:

internal static extern int InternalGetHashCode(object obj);

So how it really happens is a mistery to me (there might be a pattern, but I am not going to dig deeper at this point -- maybe some sort of "pseudo random number" algorithm?). Somebody from the CLR team could answer that.

As for the other questions, Reed actually beat me to the punch re: GetHashCode and Equals. The MSDN page describes it with few more gory details, just in case.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文