Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct implementation for GetHashCode() for entity classes?

Tags:

c#

.net

orm

Below is a sample implementation of overriding Object.Equals() for an entity base class from which all other entities in an application derive.

All entity classes have the property Id, which is a nullable int. (It's the primary key of whatever table the entity class corresponds to.)

public override bool Equals(object obj)
        {
            if (obj == null || GetType() != obj.GetType())
                return false;

            if (base.Equals(obj))
                return true;

            return Id.HasValue && ((EntityBase) obj).Id.HasValue &&
                   Id.Value == ((EntityBase) obj).Id.Value;
        }

Given this implementation of Equals(), how do you correctly implement GetHashCode()?

like image 248
Josh Kodroff Avatar asked Feb 03 '09 17:02

Josh Kodroff


People also ask

How is GetHashCode implemented?

For example, the implementation of the GetHashCode() method provided by the String class returns identical hash codes for identical string values. Therefore, two String objects return the same hash code if they represent the same string value.

What is the use of GetHashCode in C#?

The GetHashCode method provides this hash code for algorithms that need quick checks of object equality. For information about how hash codes are used in hash tables and for some additional hash code algorithms, see the Hash Function entry in Wikipedia. Two objects that are equal return hash codes that are equal.

Why should you override equals and GetHashCode C#?

It is because the framework requires that two objects that are the same must have the same hashcode. If you override the equals method to do a special comparison of two objects and the two objects are considered the same by the method, then the hash code of the two objects must also be the same.


1 Answers

If you're deriving from something that already overrides GetHashCode I'd implement it as:

public override int GetHashCode()
{
    unchecked
    {
        int hash = 37;
        hash = hash * 23 + base.GetHashCode();
        hash = hash * 23 + Id.GetHashCode();
        return hash;
    }
}

A null value of Id will return 0 for Id.GetHashCode().

If your class just derives from Object, I'd just return Id.GetHashCode() - you do not want to include the object.GetHashCode implementation in your hash code, as that basically ends up being object identity.

Note that your equality definition won't return true if neither entity has an Id, but the same hashcode will be returned from both objects. You may wish to consider changing your Equals implementation.

like image 93
Jon Skeet Avatar answered Nov 10 '22 08:11

Jon Skeet