开发者

Why IEqualityComparer<T> has GetHashCode() method?

IEqualityComparer in the namespace System.Collections.Generic has following methods:

bool Equals(T x, T y);
int GetHa开发者_如何学PythonshCode(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?


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 is used in HashTables, Dictionaries and others to optimize the search. Have a look here: http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx


Because the Guidelines for Overriding Equals() and Operator == (C# Programming Guide) says:

It is recommended that any class that overrides Equals also override Object.GetHashCode.

This is because Hashtables etc expects that two objects that are equal have the same hashcode.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜