Search code examples
c#gethashcode

Does overriding the GetHashCode method mean used values should never change?


If I have a class with properties

public class a{
    public int b;
    public int c;
    public int d;
}

And I override the GetHashCode method in the class with

public class a
{
    public int b;
    public int c;
    public int d;

    public override int GetHashCode()
    {
         int hashCode = base.GetHashCode();
         hashCode = hashCode * -1521134295 + a.GetHashCode();
         hashCode = hashCode * -1521134295 + b.GetHashCode();
         hashCode = hashCode * -1521134295 + c.GetHashCode();
         return hashCode;
    }

   public override bool Equals(){
   ...
   }
}

Does this mean that a, b, or c should never change? Otherwise the GetHashCode method becomes useless? Due to the fact that changing properties will generate different hashcodes, and the object at one time does not equal the object at another later state? Usually this should probably be correct, but I am having weird binding issues that seem to suggest I should not be doing this.

I think I was reading something on this, but I wanted to verify that this is true. It just seems like properties change in objects all the time, so it doesn't seem even safe to even override GetHashCode() for 99% of my use cases, where you don't want things to break if you change the object, if this is the case.

Thanks.

override without repurcussions


Solution

  • Basically yes, if you are using the class in some data structure which stores it relying on the hash code value (like a key in the dictionary for example), then values used to calculate the hash code should remain the same.

    Docs for Object.GetHashCode have a section on this topic, called Notes to Inheritors. In short you should try avoiding overriding GetHashCode for mutable reference types:

    You can override GetHashCode() for immutable reference types. In general, for mutable reference types, you should override GetHashCode() only if:

    • You can compute the hash code from fields that are not mutable;
    • You can ensure that the hash code of a mutable object does not change while the object is contained in a collection that relies on its hash code.

    Otherwise, you might think that the mutable object is lost in the hash table. If you do choose to override GetHashCode() for a mutable reference type, your documentation should make it clear that users of your type should not modify object values while the object is stored in a hash table.

    Similar advice can be found also in the Equality Operators doc.