Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GetHashCode Equality

I've wondered about this, so I figure I'll ask it.

Most places you'll see use the same semantic logic for overriding Equals as GetHashCode for memberwise equality...however they usually use different implementations:

    public override bool Equals(object obj)
    {
        if (obj == null || GetType() != obj.GetType())
        {
            return false;
        }
        var other = (MyType)obj;
        if (other.Prop1 != Prop1)
        {
            return false;
        }
        return true;
    }

    public override int GetHashCode()
    {
        int hash = -657803396;
        num ^= Prop1.GetHashCode();
        return num;
    }

If you're implementing memberwise equality for your type (lets say for storing in a dictionary), why not just override GetHashCode then do something like this for Equals:

    public override bool Equals(object obj)
    {
        return this.HashEqualsAndIsSameType(obj);
    }

    public static bool HashEquals(this object source, object obj)
    {
        if (source != null && obj != null)
        {
            return source.GetHashCode() == obj.GetHashCode();
        }
        if (source != null || obj != null)
        {
            return false;
        }
        return true;
    }

    public static bool HashEqualsAndIsSameType<T>(this T source, object obj)
    {
        return (obj == null || obj.GetType() == typeof(T)) && source.HashEquals(obj);
    }
like image 598
Jeff Avatar asked Oct 12 '10 05:10

Jeff


1 Answers

Because there is a real risk of conflicts. Hash-codes are not unique. They can (when different) prove inequality, but never equality. When looking for an item:

  • get the hash-code(s)
  • if the hash-code is different, the object is different; discard it
  • if the hash-code is the same, check Equals:
  • if Equals reports true they are the same
  • else discard

Consider long... since hash-code is int, it is easy to see that there are lots and lots of conflicts.

like image 56
Marc Gravell Avatar answered Sep 29 '22 08:09

Marc Gravell