Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.Net Dictionary and the Overriding of Equals

I know that when I create a dictionary with a custom class as key, the match when I provide a key is done through reference compare. For example:

public class SomeClass
{
    public object SomeValue { get; set; }
}

// ....
public static void Main()
{
    var dict = new Dictionary<SomeClass, string>();

    var key1 = new SomeClass { SomeValue = 30 };
    dict[key1] = "30";

    Console.WriteLine(dict[key1]); // prints "30"

    var key2 = new SomeClass { SomeValue = 30 };
    Console.WriteLine(dict[key2]); // prints null 
}

What happens if I override Equals (and ==) in the SomeClass class? Will I get "30" on the second line of the output?

And what if I want to have a dictionary that is based on references instead of member values, but I have overridden Equals?

Thanks!!

like image 831
Bruno Brant Avatar asked Nov 23 '10 23:11

Bruno Brant


1 Answers

Short Answer

Yes if you override Equals and GetHashCode methods your custom key comparison will start working.

Long Answer

The Dictionary<TKey,TValue> class does not necessarily do a reference based comparison. It instead uses the IEqualityComparer<TKey> instance which can be provided to the constructor. If not provided the default is EqualityComparer<T>.Default.

The processes by which EqualityComparer<T>.Default works is complicated. But a summary is

  • Looks for IEquatable<T> on the type and if present it is used for equality
  • Defaults to using the Equals method which by default is Object.Equals and hence a reference comparison

So types can override the the comparison at a couple of levels

  • By specifying a custom IEqualityComparer<T>
  • Implementing IEquatable<T> and overriding GetHashCode
  • Overriding Equals and GetHashCode

The equality operators == and != do not come into play for the TKey type in a Dictionary<TKey,TValue>.

like image 88
JaredPar Avatar answered Sep 25 '22 23:09

JaredPar