6

I am trying to understand what the object.GetHashCode() is used for. I read that it is used by collections to uniquely identify keys. But I wanted to test this and the result isn't what I expected.

struct Animal
{
    public string Name { get; set; }
    public int Age { get; set; }

    public Animal(string name, int age) : this()
    {
        Name = name;
        Age = age;
    }

    public override int GetHashCode()
    {
        return Age.GetHashCode();
    }
}

object doggy = new Animal("Dog", 25);
object cat = new Animal("Cat", 25);

Hashtable table = new Hashtable();
table.Add(doggy, "Dog");
table.Add(cat, "Cat");

Console.WriteLine("{0}", table[cat]);
Console.WriteLine("{0}", table[doggy]);

I would have expected "Cat" would overwrite "Dog" or some kind of error telling me that the "key already exists" but the output is

"Cat" "Dog"

Felipe Oriani
  • 37,948
  • 19
  • 131
  • 194
Mads Lee Jensen
  • 4,570
  • 5
  • 36
  • 53
  • 3
    btw - it isn't related to the question, but `struct` is a very poor choice for this scenario. If in doubt, use `class`. If not in doubt, probably still use `class`. It is *exceedingly* rare to (validly) declare a `struct` in C#. – Marc Gravell Sep 07 '10 at 19:10
  • Yeah i agree, actually the test was originally with class, but i tried replacing to struct to see if it made eny difference :) – Mads Lee Jensen Sep 10 '10 at 14:02

2 Answers2

12

GetHashCode is only the first check, used to determine non-equality and possible equality. After that, Equals is checked. Which for objects defaults to reference-equality, and for structs is a memberwise compare. Override Equals to give an appropriate implementation (paired with the hash-code), and it should give the results you expect (duplicate key).

btw, the IDE is probably already giving you a warning that GetHashCode and Equals should always be treated together...

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • As an addition, MSDN states: "Derived classes that override GetHashCode must also override Equals to guarantee that two objects considered equal have the same hash code; otherwise, the Hashtable type might not work correctly." http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx – Anthony Pegram Sep 07 '10 at 19:09
2

Hash codes are used as a first check to divide objects into groups. If a collection holds the hash code of each item therein, it can search for an item by first searching for items whose hash code matches that of the item sought. Once it finds one or more such items, it can examine them in more detail. Ideally, objects which are not equal would always return different hash codes, but that's not practical. If objects which are not equal return identical hash codes, it may be necessary to examine all of them in detail any time one of them is sought.

supercat
  • 77,689
  • 9
  • 166
  • 211