Reputation: 63190
I have written a whole bunch of objects that are all parts of collections and on which I will need to do lots of sort and search. On most of these object I have implemented and overridden the Equals
method, IEquatable
and operator!
and operator==
.
Now I come to wanting to use List<T>.Sort
on an object having implemented all above and it turns out I need to implement IComparable
to do custom sorting.
Why does Sort use IComparable
and what is then the point of having IEquatable
in all my objects?
Also what does Object.Equal
overriding have to do with all this?
Upvotes: 12
Views: 554
Reputation: 11592
Equality tells you if two instances are equal. Comparability tells you how to sort them.
You override the instance version of Object.Equals
when you know better than the runtime how equality works for your type.
Equality for reference types is defaulted to Reference Equality (same reference is the same object).
object o1 = new object();
object o2 = o1;
if(o2==o1)
{
Console.WriteLine("These reference types are equal");
}
object o3 = new object();
if(o2 != o3)
{
Console.WriteLine("These reference types are not equal");
}
Default equality for value types means that all member variables are equal. You should generally override Equals for value types, because you'll likely know better what equals means.
How this effects comparability is that comparability does somewhat rely on equality. In order to know what it means to be less than or greater than you need to know what equal to means.
Upvotes: 0
Reputation: 10487
Using the IEquatable
interface you define an equivalence relation, but for sorting you need an ordering.
Upvotes: 0
Reputation: 174299
Well, as you can see in the other questions about this topic, IEquatable<T>
checks for equality, while IComparable<T>
introduces a rank which is needed for sorting.
Upvotes: 0
Reputation: 1062745
It can't possibly use IEquatable<T>
to sort - knowing whether two things are equals doesn't help you rank them. However, it can use IComparable<T>
if your types implement it, or any IComparer<T>
(including Comparer<T>.Default
) to provide a custom comparer object. The functional style (Comparison<T>
) is convenient too, for ad-hoc sorting without lots of code:
list.Sort((x,y) => string.Compare(x.Name, y.Name));
but if you just want a simple ordinal sort, have your T
implement IComparable<T>
, and just use:
list.Sort();
Upvotes: 15
Reputation: 15559
Because sorting relies not on just equality but relative rank. In order to sort you need to know the position of objects relative to each other. Greater Than, Less Than, Equal.
Upvotes: 4
Reputation: 1500335
Equality can only give you a result of whether two objects are equal or not. It can't tell you whether x
should come before or after y
in the sorted order. Given only equality, how would you propose that List<T>
should perform any sorting?
The point of implementing IEquatable<T>
is for when it's equality which is important, e.g. in HashSet<T>
or as the key type in a Dictionary<TKey, TValue>
. Likewise, those couldn't be implemented efficiently using only IComparable<T>
, as it wouldn't provide a hash code.
The two interfaces are basically used in different situations.
Upvotes: 7
Reputation: 2441
Because IComparable
allows to determine if an object is "smaller" or "bigger" than another object, whereas IEquatable
helps finding out whether two objects are "equal".
The former is needed for sorting, because just knowing which objects are of equal value doesn't help you putting them in a specific order.
Upvotes: 4