Can I write a hash code function for the following comparer logic?
Two instances of My
are equal if at least two properites from (A, B, C) match.
The Equals part is simple, but I'm stumped on the hash code part, and part of me is thinking it might not be possible.
class MyOtherComparer : IEqualityComparer<My>
{
public bool Equals(My x, My y)
{
if (Object.ReferenceEquals(x, y))
return true;
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
int matches = 0;
if(x.A == y.A) matches++;
if(x.B == y.B) matches++;
if(x.C == y.C) matches++;
// match on two out of three
return (matches > 1)
}
// If Equals() returns true for a pair of objects
// then GetHashCode() must return the same value for these objects.
public int GetHashCode(My x)
{
// ???
}
}
UPDATE: In addition to the correct answer by Reed Copsey, a very important point about the general usefulness of a fuzzy comparer is clearly stated by Ethan Brown - please see his answer as well for a full understanding of what underlies this Question/Answer.
Yes, it's possible. The simplest implementation would be to always return a constant.
public int GetHashCode(My x)
{
return 0;
}
The GetHashCode documentation states:
Implementations are required to ensure that if the Equals method returns true for two objects x and y, then the value returned by the GetHashCode method for x must equal the value returned for y.
However, you are perfectly free to return the same hash code for two objects which are not equal, as well.
That being said, this will potentially cause some algorithms to perform very poorly, as you'll get lots of hash collisions. However, given the nature of your odd/unique equality check, this may be required.
Note that this is going to be problematic in any case. Given your logic, it's possible to have three objects, where comparer.Equals(foo, bar)==true
and comparer.Equals(foo, baz)==true
but comparer.Equals(baz, bar)==false
. This is likely to be problematic in many cases where IEqualityComparer<T>
is used.