We all know about the requirement where we must override both Equals and GetHashCode if any one of them needs changing due to custom login in our application. Just wanted to throw more light on why is this required and how it can behave otherwise.
The default implementation for GetHashCode() returns an internal hashcode of the object(which is not its memory address or anything like that) and the default implementation for Equals() just checks the hashcodes and returns true if they match and false if they don’t.
Now the case of overriding comes in when a custom logic is required. For example, you Implement ICloneable interface and implement the clone() method on your custom type called Person. This class has two public properties Name and Age. When you clone a person, you return another(new) instance of Person class with the same Name and Age. Given this logic, its quite expected that if anyone calls Equals() on your original Person and passes clonned person as parameter, it should return True. But the default implementation of Equals() checks the hash code, which, in this case are different, since two persons(although cloned with same properties) are distinct reference type objects on heap with their own memory addresses. So in this situation, to make your Equals() method fall inline with overall logic of Person class, you’d have to overrride the Equals() method.
But if you don’t override GetHashCode(), then if your Person class is used with Dictonaries and Hashtables, which rely completely on hash codes, then our class will mis-behave, for example, if you add a person to Dictionary and then clone it and pass the cloned object to Contains() methods of Dictonary, it will return false by default because it finds that the hashcode for both these objects are different. This may be counter-intuitive to Person class logic because a clonned person should be considered equal to its original and the dictionary/hastables objects have to honour this. So can you override GetHasCode(), where you check that if those two public properties are same then the same hashcode must be returned, then your class will work properly with Dictonaries. But the key point here is to make sure that GetHashCode() in this case, is using an immutable private field to generate the HashCode so that the no body can cause the hashcode to change from outside. After all, the hash codes have to remain identical as long as their Equals() continues to return true.