C# User class. GetHashCode implementation

724 views Asked by At

I have simple class only with public string properties.

public class SimpleClass
{
    public string Field1 {get; set;}
    public string Field2 {get; set;}
    public string Field3 {get; set;}
    public List<SimpleClass> Children {get; set;}

    public bool Equals(SimpleClass simple)
    {
        if (simple == null)
        {
            return false;
        }
        return IsFieldsAreEquals(simple) && IsChildrenAreEquals(simple);
    }

    public override int GetHashCode()
    {
        return RuntimeHelpers.GetHashCode(this); //Bad idea!
    }
}

This code doesn't return same value for equal instances. But this class does not have readonly fields for compute hash.

How can i generate correct hash in GetHashCode() if all my properties are mutable.

1

There are 1 answers

5
Jon Skeet On BEST ANSWER

The contract for GetHashCode requires (emphasis mine):

The GetHashCode method for an object must consistently return the same hash code as long as there is no modification to the object state that determines the return value of the object's Equals method.

So basically, you should compute it based on all the used fields in Equals, even though they're mutable. However, the documentation also notes:

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.

If only some of your properties were mutable, you could potentially override GetHashCode to compute it based only on the immutable ones - but in this case everything is mutable, so you'd basically end up returning a constant, making it awful to be in a hash-based collection.

So I'd suggest one of three options:

  • Use the mutable fields, and document it carefully.
  • Abandon overriding equality/hashing operations
  • Abandon it being mutable