为什么使用 IEqualityComparer有 GetHashCode() 方法吗?
命名空间 System.Collections.Generic
IEqualityComparer > 有以下方法:
bool Equals(T x, T y);
int GetHashCode(T obj);
由于该接口用于检查对象的相等性,因此第一个方法 Equals
有意义。但为什么我们还需要实现 GetHashCode
呢?为什么它首先存在于界面中?什么时候需要,为什么?
我将其与命名空间中的 Enumerable.Distinct() 方法一起使用System.Linq
,我惊讶地发现甚至 GetHashCode()
和 Equals()
也被调用。为什么? Distinct
是如何工作的?
IEqualityComparer in the namespace System.Collections.Generic
has following methods:
bool Equals(T x, T y);
int GetHashCode(T obj);
Since this inteface is used to check equality of objects, the first method Equals
makes sense. But why do we need to implement GetHashCode
also? Why does it exist in the interface in the first place? When is it needed and why?
I'm using it with Enumerable.Distinct() method in the namespace System.Linq
, and I'm surprised to see that even GetHashCode()
is getting called, along with Equals()
. Why? How does Distinct
work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
有关
Distinct
如何工作(或至少是一个简单的示例实现)的详细信息,请参阅我的 Edulinq 博客文章 (旧 - 404)。简而言之,与适当的相等比较相对应的哈希码使得创建一组项目的成本更低。这在很多情况下都很有用 - 例如
Distinct
、Except
、Intersect
、Union
code>、Join
、GroupJoin
、GroupBy
、ToLookup
等。For details on how
Distinct
works (or at least a simple example implementation) see my Edulinq blog post on it (old - 404).To put it simply, a hash code which corresponds to the appropriate equality comparison makes it cheaper to create a set of items. That's useful in a lot of situations - such as
Distinct
,Except
,Intersect
,Union
,Join
,GroupJoin
,GroupBy
,ToLookup
and so on.GetHashCode
用于HashTables
、Dictionaries
等来优化搜索。看看这里: http://msdn.microsoft.com/ en-us/library/system.object.gethashcode.aspxGetHashCode
is used inHashTables
,Dictionaries
and others to optimize the search. Have a look here: http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx因为重写 Equals() 和运算符 == 的指南(C# 编程指南) 说:
这是因为哈希表等期望两个相等的对象具有相同的哈希码。
Because the Guidelines for Overriding Equals() and Operator == (C# Programming Guide) says:
This is because Hashtables etc expects that two objects that are equal have the same hashcode.
IEqualityComparer(Of T) 的目的是允许使用在语义上与默认 Object.Equals 不同的比较方法,该方法可能会导致两个对象被视为相等,即使 Object.Equals 会认为它们不同。因为相等的对象必须具有相同的哈希码,并且由于 EqualityComparer 的 Equals 方法认为相等但 Object.Equals 认为不相等的事物可能具有不同的哈希码,因此 EqualityComparer 有必要使用不同的哈希值- 编码方法。
IEquatable(Of T) 存在更有趣的情况。如果 Object.Equals 报告两个对象不相等,则预计永远不会将两个对象报告为相等。对于任何未密封的类来说,实现 IEquatable(Of T) 都是危险的;太糟糕了,没有通用约束来禁止使用未密封的类。
The purpose of IEqualityComparer(Of T) is to allow the use of a comparison method which is semantically different from the default Object.Equals--one which may cause two objects to be considered equal even if Object.Equals would consider them different. Because equal objects must have equal hash codes, and because things which the EqualityComparer's Equals method considers equal but Object.Equals considers unequal might have different hash codes, it is necessary for the the EqualityComparer to use a different hash-coding method.
A more interesting situation exists with IEquatable(Of T). That is expected never to report two objects as equal if Object.Equals reports them unequal. For any unsealed class to implement IEquatable(Of T) is dangerous; too bad there's no generic constraint which would forbid the use of unsealed classes.