Search code examples
c#.netgethashcode

Should I use a common utility for generating a HashCode from multiple fields?


I was looking at the sourcecode for Tuple<T1,T2> and its GetHashCode() method uses this internal helper:

Int32 IStructuralEquatable.GetHashCode(IEqualityComparer comparer) {
  return Tuple.CombineHashCodes(comparer.GetHashCode(m_Item1), comparer.GetHashCode(m_Item2));
}

internal static int CombineHashCodes(int h1, int h2) {
  return (((h1 << 5) + h1) ^ h2);
}

As the comparison of objects and thus the use of GetHasCode() is such a common task I am curious to see if the CLR or .NET provides any helper/utility to do this, so one doesn't have to write the same code over and over and risk introducing an error?


Solution

  • Well, you can of course use Tuple.Create(h1, h2).GetHashCode(). With the ValueTuple that's very likely to be in the next version (for the sort of tuples that C#7 is likely to support) you won't even need an allocation.

    In the meantime though, that's about as much as you have, though there've been suggestions that there should be more.

    One pressing question though, is will it discourage people from thinking about the values; what ranges of values can be seen, will be commonly seen, etc. The code you give is not necessarily the best way to combine two integers into a hash code. If it was rare for two objects to have the same h1 then return h1 could be better. If h1 was always within a range of of 0 to 15 and h2 rarely more than a few hundred then (h1 << 4) + h2 could be better. If h1 and h2 would be set directly based on user input then you'd want to mix in a random seed to guard against hash-DoSing, etc.