0

I have a struct that overrides the Equals() method and the compiler complains about GetHashCode() not being overridden.

My struct:

  private struct Key
  {
    ...

    public override int GetHashCode()
    {
      return ?;
    }

    public int FolderID;
    public MyEnum SubItemKind;
    public int SubItemID;
  }

What is the right way to implement the GetHashCode() method?

a)

    return FolderID ^ SubItemKind.GetHashCode() ^ SubItemID;

or b)

    return FolderID.GetHashCode() ^ SubItemKind.GetHashCode() ^ SubItemID.GetHashCode();
ViRuSTriNiTy
  • 5,017
  • 2
  • 32
  • 58
  • 3
    `System.Int32.GetHashCode()` performs a simple `return this` (at least in mscorlib v4), so your two code snippets would be equivalent anyway. – Frédéric Hamidi Sep 10 '15 at 12:43
  • 1
    This question is not specific to `struct`. The core of the problem is combining multiple hash codes into one, which is explained in the top answer to the "What is the best algorithm for an overridden System.Object.GetHashCode?" question. – Sergey Kalinichenko Sep 10 '15 at 12:49

1 Answers1

3

Always the latter. The former isn't sufficient because most bits are 0 (your numbers are most likely small), and those zeroes are in the most significant bits. You'd be wasting a lot of the hash code, thus getting a lot more collisions.

Another common way of doing it is to multiply each item by a prime number and relying on overflows:

return unchecked(FolderID.GetHashCode() * 23 * 23 
                 + SubItemKind.GetHashCode() * 23 
                 + SubItemID.GetHashCode());

Edit: Updated to use unchecked for explicit overflow support as per stakx's comment.

stakx - no longer contributing
  • 83,039
  • 20
  • 168
  • 268
Blindy
  • 65,249
  • 10
  • 91
  • 131