I asked a question here : When To Use IEquatable And Why about using IEquatable.
From the msdn:
The IEquatable(T) interface is used by generic collection obj开发者_如何学编程ects such as Dictionary(TKey, TValue), List(T), and LinkedList(T) when testing for equality in such methods as Contains, IndexOf, LastIndexOf, and Remove.
If you dont implement that interface what exactly happens?? Exception / default object equals / ref equals?
If you don't implement equality comparison, the default implementation will be used.
If the key is a reference type, reference comparision is used. Unless you keep the key objects so that you can use them when retrieving items from the collection, they are lost. Creating a new key object from the same data gives you an object with a difference reference, so it will miss the item you are looking for.
Here's one example:
public class Foo : IEquatable<Foo>
{
public string Bar { get; set; }
public bool Equals(Foo other)
{
return string.Equals(other.Bar, Bar);
}
}
class Program
{
public static void Main(string[] args)
{
var foos = new List<Foo>(new[]
{
new Foo { Bar = "b1" },
new Foo { Bar = "b2" },
new Foo { Bar = "b3" },
});
var foo = new Foo { Bar = "b2" };
Console.WriteLine(foos.IndexOf(foo)); // prints 1
}
}
Now comment the IEquatable<Foo>
implementation and run the program again.
It's a bit incorrect to say that Dictionary<TKey,TValue>
uses IEquatable<T>
to compare TKey
values. It actually uses an IEquatilyComparer<T>
to compare values.
When one is not explicitly provided though it will use EqualityComparer<TKey>.Default
to generate the comparer. This static property has a heuristic to determine which is the best way to compare TKey
values. If the type TKey
implements IEqutable<TKey>
this will be used. If it's not though it will fall back to using the .Equals method directly.
So if you don't implement IEquatable<T>
and don't provide an explicity IEqualityComparer<T>
then Dictionary<TKey,TValue>
will rely on normal .Equals.
精彩评论