3

Suppose I have a class T that I want to use as a key in a Dictionary<T,U> collection.

What must I implement in T so that these keys are based on values of T rather than T references?

I'm hoping it's just GetHashCode().

Ed Guiness
  • 34,602
  • 16
  • 110
  • 145

4 Answers4

5

You must implement GetHashCode() and Equals().

Dictionary is a Hashtable below the covers, so you might want to read this: Pitfalls Of Equals/GetHashCode – How Does A Hash Table Work?

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
driis
  • 161,458
  • 45
  • 265
  • 341
3

If you don't pass any IEqualityComparer<T> in the dictionary constructor, it will use EqualityComparer<T>.Default which is defined by MSDN as :

The Default property checks whether type T implements the System.IEquatable(Of T) interface and, if so, returns an EqualityComparer(Of T) that uses that implementation. Otherwise, it returns an EqualityComparer(Of T) that uses the overrides of Object.Equals and Object.GetHashCode provided by T.

So implementing IEquatable<T> would be my choice (if you implement it it also makes sense to override Equals and GetHashCode anyway).

Julien Lebosquain
  • 40,639
  • 8
  • 105
  • 117
  • I wouldn't recommend having any inheritable type implement IEquatable, since bad things will happen if a derived type overrides Object.Equals(Object) and/or Object.GetHashCode(Object) and the implementation of IEquatable doesn't call those overrides; since casting to Object to call those overrides would defeat any advantage obtained from using the generic interface, there's really no point to implementing it. – supercat Aug 23 '11 at 19:24
3

Either implement Equals and GetHashCode or create an appropriate IEqualityComparer<T> which has the right form of equality matching for your map.

I rather like the IEqualityComparer<T> route: in many cases there isn't one obviously-right form of equality - you want to treat objects as equal in different ways depending on the situation. In that case, a custom equality comparer is just what you need. Of course, if there is a natural equality operation, it makes sense to implement IEquatable<T> in the type itself... if you can. (Another benefit of IEqualityComparer<T> is that you can implement it for types you have no control over.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
2

You need to override Equals(object obj). It is always expected that you implement GetHashCode when you modify Equals. Read this article at MSDN.

C. Ross
  • 31,137
  • 42
  • 147
  • 238