Implementing IEquatable is not enough to use a class as a Dictionary key

Note to future self: it is not enough to implement IEquatable<T> to use a class as a Dictionary key.

Today I needed a Dictionary with a composite key, a combination of several values. So I quickly cooked up a class with public properties to cover the values and for ease of use, a constructor to quickly set those values. But to be able to use it as a dictionary key, I would need a little more. Per default, classes are only checked for reference equality, which makes sense. But I would need to have the system evaluate two separate instances of this class as equal, if all of their properties were equal.

That would not be too hard. The documentation for Dictionary<TKey, TValue> (see Remarks section) states:

If type TKey implements the System.IEquatable<T> generic interface, the default equality comparer uses that implementation.

Great! I quickly added an implementation that compared all of the properties and fired up my application. All retrieval attempts from the dictionary failed, they did not return any results. I set a breakpoint on my Equals implementation only to find it was never hit.

public class SlabProperties: IEquatable<SlabProperties> {
    // ...
    public bool Equals(SlabProperties other) {
    // ...

As it turned out, I had been a little too quick. Implementing IEquatable is not enough! It is not obvious from the documentation (at least it wasn’t to me), but you also have to override GetHashCode(), because the dictionary relies on it to distinguish keys before it even looks at Equals(). After I added a GetHashCode() override, suddenly the Equals implementation was hit and the dictionary worked as I had intented.

As a bonus, adding GetHashCode() was easily done using my favorite ReSharper plugin: hit Alt+Ins, Equality members. Tick the properties that need to be included in the comparison, and all the necessary code is generated for you. But, of course, it is also not that hard to add it on your own, just don’t forget to do that.

Advertenties

Over Shiftkey
I am Maarten, owner of and chief software developer for Shiftkey software development from The Netherlands. I will be writing mainly about things I run into when programming in C# or Delphi.

Geef een reactie

Vul je gegevens in of klik op een icoon om in te loggen.

WordPress.com logo

Je reageert onder je WordPress.com account. Log uit / Bijwerken )

Twitter-afbeelding

Je reageert onder je Twitter account. Log uit / Bijwerken )

Facebook foto

Je reageert onder je Facebook account. Log uit / Bijwerken )

Google+ photo

Je reageert onder je Google+ account. Log uit / Bijwerken )

Verbinden met %s

%d bloggers liken dit: