May 15, 2009

Again* on overriding Object.GetHashCode()

Overriding Object.GetHashCode can rightfully be regarded as one of the more mundane tasks in .NET programming and indeed, often enough, when your own application is the only consumer of your code, you might as well return 42 (don't do it, though!).

However, if you're writing reusable components or if you're implementing types that you plan to use as keys in an IDictionary, you are required to provide (at the very least) a decent hash function implementation.

The hashing algorithm advocated by Joshua Bloch in his Effective Java is widely regarded as a good enough algorithm for most circumstances (think non performance critical). It's also very easy to implement, as per the sketch below:

  1. choose a non zero initial value and store it in a variable h
  2. choose an odd prime multiplier and store it in variable m
  3. for each relevant member field f (also used in evaluating this.Equals) do: h = h * m + f.GetHashCode()
  4. return h as the hash code
One thing I would recommend is encapsulating this into a utility method (or class, depending on the degree of API flexibility you want) for ease of reuse. The second (and I know I'm being somewhat pedantic) is surrounding the arithmetic operations in an unchecked block. Arithmetic overflow is bound to happen (and that's fine), but even if by default operations involving variables (unlike constants) are implicitly executed in an unchecked context, you can never be sure that the client code doesn't call your GetHashCode inside an explicit checked block, exposing itself to an unwanted OverflowException.

* No, my role in the team is not to implement Equals and GetHashCode all across our codebase :)

No comments: