问题标签 [gethashcode]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
22 回答
258494 浏览

.net - 覆盖 GetHashCode 的最佳算法是什么?

在 .NET 中,该GetHashCode方法在整个 .NET 基类库中的很多地方都使用。正确实施它对于在集合中快速查找项目或确定相等性时尤为重要。

是否有关于如何GetHashCode为我的自定义类实现的标准算法或最佳实践,这样我就不会降低性能?

0 投票
6 回答
65427 浏览

.net - Object.GetHashCode() 的默认实现

默认实现如何GetHashCode()工作?它是否有效且足够好地处理结构、类、数组等?

我试图决定在什么情况下我应该自己打包,在什么情况下我可以安全地依赖默认实现来做好。如果可能的话,我不想重新发明轮子。

0 投票
11 回答
133399 浏览

c# - .NET 唯一对象标识符

有没有办法获取实例的唯一标识符?

GetHashCode()对于指向同一个实例的两个引用是相同的。但是,两个不同的实例可以(很容易)获得相同的哈希码:

我正在编写一个调试插件,我需要获取某种 ID 用于在程序运行期间唯一的引用。

我已经设法获得了实例的内部地址,它是唯一的,直到垃圾收集器 (GC) 压缩堆(= 移动对象 = 更改地址)。

堆栈溢出问题Object.GetHashCode() 的默认实现可能是相关的。

这些对象不受我的控制,因为我正在使用调试器 API 访问正在调试的程序中的对象。如果我可以控制这些对象,那么添加我自己的唯一标识符将是微不足道的。

我想要用于构建哈希表 ID -> 对象的唯一 ID,以便能够查找已经看到的对象。现在我这样解决了:

0 投票
9 回答
6182 浏览

c# - GetHashCode 扩展方法

在阅读了 StackOverflow 上有关覆盖的所有问题和答案后,GetHashCode()我编写了以下扩展方法,以便轻松方便地覆盖GetHashCode()

(我基本上只重构了有人贴在那里的代码,因为我很喜欢它可以通用)

我这样使用:

你看到这段代码有什么问题吗?

0 投票
2 回答
3659 浏览

c# - 我需要在引用类型上覆盖 GetHashCode() 吗?

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

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

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

我将分解我的问题:

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

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

0 投票
4 回答
903 浏览

c# - C# 如何为违反 Equals 合约的类选择 Hashcode?

由于某些原因,我有多个课程不遵守官方Equals合同。在被覆盖的情况下,GetHashCode()这些类只返回 0,因此它们可以在 Hashmap 中使用。

其中一些类实现了相同的接口,并且有使用该接口作为键的 Hashmaps。所以我认为每个类至少应该在GetHashCode().

问题是如何选择这个值。我应该简单地让第一个类返回 1,下一个类返回 2,依此类推吗?或者我应该尝试类似的东西

所以哈希分布更均匀?(我必须自己缓存返回的值还是微软的编译器能够对此进行优化?)

更新:不可能为每个对象返回单独的哈希码,因为 Equals 违反了合同。具体来说,我指的是这个问题

0 投票
5 回答
10398 浏览

c# - 为可变对象覆盖 GetHashCode?

我已经阅读了大约 10 个关于何时以及如何覆盖的不同问题,GetHashCode但仍有一些我不太明白的问题。的大多数实现GetHashCode都是基于对象字段的哈希码,但有人指出,GetHashCode在对象的生命周期内,值永远不会改变。如果它所基于的字段是可变的,那它是如何工作的?另外,如果我确实希望字典查找等基于引用相等而不是我的覆盖Equals怎么办?

我主要是Equals为了便于对我的序列化代码进行单元测试而重写,我假设序列化和反序列化(在我的情况下为 XML)会杀死引用相等,所以我想确保它至少通过值相等是正确的。Equals在这种情况下,这是一种不好的做法吗?基本上在大多数执行代码中,我想要引用相等,我总是使用==并且我没有覆盖它。我应该只创建一个新方法ValueEquals或其他东西而不是覆盖Equals吗?我曾经假设框架总是使用==而不是Equals比较事物,所以我认为重写它是安全的,Equals因为在我看来,它的目的是如果你想要一个不同于==操作员。从阅读其他几个问题来看,情况似乎并非如此。

编辑:

似乎我的意图不清楚,我的意思是 99% 的时间我想要简单的旧引用相等,默认行为,没有意外。对于非常罕见的情况,我想要值相等,并且我想通过使用.Equals而不是显式请求值相等==

当我这样做时,编译器建议我也覆盖GetHashCode,这就是这个问题的出现方式。GetHashCode当应用于可变对象时,似乎存在矛盾的目标,这些目标是:

  1. 如果a.Equals(b)那么a.GetHashCode()应该== b.GetHashCode()
  2. 的值在a.GetHashCode()的生命周期内永远不会改变a

当一个可变对象时,这些看起来自然是矛盾的,因为如果对象的状态发生变化,我们期望 的值发生.Equals()变化,这意味着GetHashCode应该改变以匹配 的变化.Equals(),但GetHashCode不应该改变。

为什么会出现这种矛盾?这些建议是否不适用于可变对象?可能是假设的,但可能值得一提的是,我指的是类而不是结构。

解析度:

我将 JaredPar 标记为已接受,但主要用于评论交互。总结一下我从中学到的是,实现所有目标并避免极端情况下可能出现的古怪行为的唯一方法是仅覆盖EqualsGetHashCode基于不可变字段,或实现IEquatable. 这种似乎减少了覆盖Equals引用类型的用处,因为据我所见,大多数引用类型通常没有不可变字段,除非它们存储在关系数据库中以用它们的主键来识别它们。

0 投票
2 回答
2854 浏览

c# - Equals 方法实现助手 (C#)

每次我写一些数据类时,我通常都会花很多时间来编写 IEquatable 实现。

我写的最后一节课是这样的:

实施 IEquatable 非常麻烦。当然 C#3.0/LINQ 有很大帮助,但是顶点可以移动和/或以相反的顺序移动,这给 Equals 方法增加了很多复杂性。经过多次单元测试和相应的实现,我放弃了,并将我的应用程序改为只接受三角形,而 IEquatable 实现只需要 11 个单元测试就可以完全覆盖。

有什么工具或技术可以帮助实现 Equals 和 GetHashCode?

0 投票
7 回答
7618 浏览

c# - 使用 xor 的 GetHashCode() 问题

我的理解是,您通常应该将 xor 与 GetHashCode() 一起使用来生成一个 int,以通过其值(而不是通过其引用)来识别您的数据。这是一个简单的例子:

这个想法是,我想根据属性 A 和 B 的值将 Foo 的一个实例与另一个实例进行比较。如果 Foo1.A == Foo2.A 和 Foo1.B == Foo2.B,那么我们就有相等性。

这是问题所在:

这些都为 GetHashCode() 生成值 3,导致 Equals() 返回 true。显然,这是一个简单的示例,并且只有两个属性,我可以简单地比较 Equals() 方法中的各个属性。但是,对于更复杂的类,这将很快失控。

我知道有时只设置一次哈希码并始终返回相同的值是很有意义的。但是,对于需要评估相等性的可变对象,我认为这是不合理的。

在实现 GetHashCode() 时处理可以轻松互换的属性值的最佳方法是什么?

也可以看看

覆盖 System.Object.GetHashCode 的最佳算法是什么?

0 投票
2 回答
5296 浏览

c# - 我应该如何实现 Object.GetHashCode() 来实现复杂的相等性?

基本上,到目前为止,我有以下内容:

所以,问题是这样的:我有一个非必填字段Guid,它是一个唯一标识符。如果没有设置,那么我需要尝试根据不太准确的指标来确定相等性,以尝试确定两个对象是否相等。这工作正常,但它使GetHashCode()混乱......我应该怎么做?一个天真的实现是这样的:

但是这两种类型的哈希冲突的可能性有多大?当然,我不希望它是1 in 2 ** 32。这是一个坏主意,如果是这样,我应该怎么做?