When you override Equals
and GetHashCode
you are changing the way the object will determine if it is equals to another. And a note, if you compare objects using ==
operator it will not have the same behavior as Equals
unless you override the operator as well.
Doing that you changed the behavior for a single class, what if you need the same logic for other classes? If you need a "generic comparison". That is why you have IEqualityComparer
.
Look at this example:
interface ICustom
{
int Key { get; set; }
}
class Custom : ICustom
{
public int Key { get; set; }
public int Value { get; set; }
}
class Another : ICustom
{
public int Key { get; set; }
}
class DicEqualityComparer : IEqualityComparer<ICustom>
{
public bool Equals(ICustom x, ICustom y)
{
return x.Key == y.Key;
}
public int GetHashCode(ICustom obj)
{
return obj.Key;
}
}
I have two different classes, both can use the same comparer.
var a = new Custom { Key = 1, Value = 2 };
var b = new Custom { Key = 1, Value = 2 };
var c = new Custom { Key = 2, Value = 2 };
var another = new Another { Key = 2 };
var d = new Dictionary<ICustom, string>(new DicEqualityComparer());
d.Add(a, "X");
// d.Add(b, "X"); // same key exception
d.Add(c, "X");
// d.Add(another, "X"); // same key exception
Notice that I didn't have to override Equals
, GetHashCode
in neither of the classes. I can use this comparer in any object that implements ICustom
without having to rewrite the comparison logic. I can also make an IEqualityComparer
for a "parent class" and use on classes that inherit. I can have comparer that will behave in a different way, I can make one to compare Value
instead of Key
.
So IEqualityComparer
allows more flexibility and you can implement generic solutions.