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();
2
  • 3
    System.Int32.GetHashCode() performs a simple return this (at least in mscorlib v4), so your two code snippets would be equivalent anyway. Commented Sep 10, 2015 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. Commented Sep 10, 2015 at 12:49

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Don't forget to wrap the whole expression in an unchecked(…) block, otherwise you might get an exception due to possible arithmetic overflows.
Didn't know he commented on the subject, yeah unchecked makes sense.
I hope you don't mind the code edit. You don't need a unchecked { … } block. You can use the variant for just one in-line expression (unchecked (…), i.e. with parentheses).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.