Generating Hash Code

All object instances can provide an signed 32-bit integer hash of their contents via the GetHashCode() method on System.Object. Good hashes can have a dramatic effect on Hashtable speed (they are used to determine which bucket to add entries to in the hashtable), and can also provide a low-fidelity (but possibly more efficient) equivalence test. Using GetHashCode in this way is demonstrated in the following examples:

void Enroll(Student s, CourseList cl) {
  hashtable.Add(s, cl); // GHC called on key (s)
}
bool FastCompare(Student s1, Student s2) {
  // Use GHC to test for possible equivalence
  if (s1.GetHashCode() != s2.GetHashCode()) return false;
  
  // Use Equals to test for definite equivalence
  return s1.Equals(s1);
}

The default implementation of GetHashCode() on System.Object returns a semi-unique member #, while the implementation of GetHashCode() on System.ValueType merely returns the hash of the first field in the value type. Although these defaults work in a lot of cases, there are sometimes performance benefits gained from implementing GetHashCode() on your own type. Additionally, if a type overrides the Equals() method, it is required to override the GetHashCode() method, which means that many framework types override GetHashCode(), as shown here:

void DumpHashes(object o, int i, Version v) {
  Console.WriteLine(o.GetHashCode()); // object index
  Console.WriteLine(i.GetHashCode()); // integer value
  Console.WriteLine(v.GetHashCode()); // hash of fields
}

The Object.GetHashCode ...

Get C# in a Nutshell now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.