What is the best way to implement GetHashCode() for class with lots of properties?

StackOverflow https://stackoverflow.com/questions/23468671

  •  15-07-2023
  •  | 
  •  

Question

I have a class that has lots of properties that I am implementing IEquitable<T> on. I have found multiple examples on how to do GetHashCode() for small amount of properties.

Here is one example

public override int GetHashCode()
{
    unchecked // Overflow is fine, just wrap
    {
        int hash = 17;
        // Suitable nullity checks etc, of course :)
        hash = hash * 23 + field1.GetHashCode();
        hash = hash * 23 + field2.GetHashCode();
        hash = hash * 23 + field3.GetHashCode();
        return hash;
    }
}

How should I go around when I have hundreds of properties on object?

Was it helpful?

Solution 2

Calculate hashcode on all property values:

public override int GetHashCode()
{
    int hashCode = this.GetHashCodeOnProperties();
    return hashCode;
}

Define this extension method (which is reusable):

public static class HashCodeByPropertyExtensions
{
    public static int GetHashCodeOnProperties<T>(this T inspect)
    {
        return inspect.GetType().GetProperties().Select(o => o.GetValue(inspect)).GetListHashCode();
    }

    public static int GetListHashCode<T>(this IEnumerable<T> sequence)
    {
        return sequence
            .Where(item => item != null)
            .Select(item => item.GetHashCode())
            .Aggregate((total, nextCode) => total ^ nextCode);
    }
}

OTHER TIPS

Spend the money to get a tool like Resharper, then just do Alt+Ins then E. This will bring up the "Generate Equality Members" dialog

enter image description here

From there just check the 100 boxes you need and it will autogenerate the GetHashCode() and Equals() functions for you

enter image description here
(the above took about 10 seconds to create)

Resharper does so much more too that it makes it worth the $150 for a personal license (you can use a personal license for work related activities without violating it, I checked). And if you are not making enough money as a programmer to afford a one time investment of $150 you really should start looking elsewhere to work as you are being very underpaid. (If you don't make any money as a programmer as you are working on a open source project Resharper is free for development teams of open source projects)

Old questions sometimes have new better answers HashCode.Combine:

public override int GetHashCode()
{
    return HashCode.Combine(field1, field2, field3);
}

Might use this as well.. Just the overhead being a new instance of everytime you call GetHash().

new { A = Prop1, B = Prop2, C = Prop3, D = Prop4 }.GetHashCode();

If all of those properties contribute to the equality of the object (if you are not overriding equality why are you overriding GetHashCode?), then they need to include all those properties in GetHashCode.

Remember equal objects must have equal hash codes.

Better perhaps to address the question raised in the comment on the question by Max and avoid the situation. Part of this might be to consider if such types should have value semantics (equality defined by their value: is an aggregate of the value of their properties), and switch to reference semantics (each instance is unique).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top