简体   繁体   中英

Why IEqualityComparer<T> has GetHashCode() method?

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM