3

Possible Duplicate:
Why is it important to override GetHashCode when Equals method is overriden in C#?

I was looking into the following class in my Object Model and could not understand the significance of adding GetHashCode() in the Class.

Sample Class

public class SampleClass
{

    public int ID { get; set; }
    public String Name { get; set; }
    public String SSN_Number { get; set; }

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

        SampleClass cls = (SampleClass)obj;
        return (ID == cls.ID) &&
               (Name == cls.Name) &&
               (SSN_Number == cls.SSN_Number);
    }

    public override int GetHashCode()
    {
        return ID.GetHashCode() ^ Name.GetHashCode() ^ SSN_Number.GetHashCode();
    }
}

Suppose I have a list of Sample Class Object and I want to get a specific index. Then Equals() can help me to get that record. Why should I use GetHashCode() ?

Community
  • 1
  • 1
Pankaj
  • 9,749
  • 32
  • 139
  • 283

2 Answers2

1

You need to handle both, because GetHashCode() is used by many collection implementations (like Dictionary) in concert with the Equals method. The important thing is that if you override the implementation of Equals, then you must override GetHashCode in such a way that any two objects that are Equal according to your new implementation also must return an identical Hash Code.

If they don't, then they will not work in Dictionary's properly. It's generally not that hard. One way that I often times do this is by taking the Properties of an object that I use for equality, and joining them together in a String object, and then return String.GetHashCode.

String has a pretty good implementation of GetHashCode that returns a wide range of integers for various values that make for good spreads in a sparse collection.

Nick
  • 5,875
  • 1
  • 27
  • 38
  • Also important for Linq-to-objects. – spender Jun 21 '12 at 16:13
  • @spender That's generally because those LINQ methods use either a Dictionary or a HashSet internally. – Servy Jun 21 '12 at 16:26
  • And ILookup too..., but yes, a general reliance on HashTable-esque collections. – spender Jun 21 '12 at 16:50
  • Your suggestion of `ToString.GetHashCode` is brilliant, and worked perfectly for me. I'm creating a stripped-down version of the `Drawing.Size` structure called `Area` for simple row/column purposes like table and grid sizes. I was going to do `width*height` for `GetHashCode`, but that could have run into multiplication overflows. I also thought of CRC, but that seemed too intensive. Your solution is perfect. Thanks. – spinjector Oct 24 '22 at 15:52
0

It is necessary to provide an override to GetHashCode, when your custom class overrides Equals. If you omit GetHashCode, you will get a compiler warning saying "A public type overrides System.Object.Equals but does not override System.Object.GetHashCode".

GetHashCode returns a value based on the current instance that is suited for hashing algorithms and data structures such as a hash table. Two objects that are the same type and are equal must return the same hash code to ensure that instances of System.Collections.HashTable and System.Collections.Generic.Dictionary<TKey, TValue> work correctly.

Suppose it was not necessary to override the GetHashCode in your custom class, the hash based collections would have to then use the base class' Object.GetHashCode which might not give correct results for all instances of your custom class.

If you observe the code you have posted, your Equals method compares ID, Name and SSN for the 2 instances to return equality result and the same attributes are being used for the hashing algorithm (ID^Name^SSN) inside your GetHashCode method.

S2S2
  • 8,322
  • 5
  • 37
  • 65