I am trying to understand the difference between two overloads of Enumerable.Except
method i.e.
Obviously, the first differnce is that the first overload uses the default equality comparer while the other uses an IEqualityComparer, but I can achieve the same result with first method, by implementing an IEquatable interface (as mentioned in the MSDN documentation of Except
method), then why this second overload is needed?
Two reasons:
You can only implement IEquatable<T>
for your own types... whereas you can specify an IEqualityComparer<T>
for any type, whether you can modify it yourself or not.
There may be multiple ways of comparing a type for equality, but implementing IEquatable<T>
only allows you to express one of them.
A simple example of all of this would be strings - consider:
string[] x = { "A", "B", "C" };
string[] y = { "A", "c" };
var bc = x.Except(y);
var justB = x.Except(y, StringComparer.OrdinalIgnoreCase);
We might want both results in different circumstances, which means we couldn't handle both with IEquatable<T>
... and we can't change how string
implements IEquatable<T>
anyway. (You're not limited to StringComparer
of course - you could write an equality comparer which just used the length of the string, for example.)
This isn't specific to LINQ, either - it's generally the case for any API which deals in equality, e.g. HashSet<>
, Dictionary<,>
etc.