Tony The Lion
Tony The Lion

Reputation: 63190

List<T> Sort uses Comparer<T> instead of IEquatable, Why?

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

Answers (7)

Matt Ellen
Matt Ellen

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

Waldheinz
Waldheinz

Reputation: 10487

Using the IEquatable interface you define an equivalence relation, but for sorting you need an ordering.

Upvotes: 0

Daniel Hilgarth
Daniel Hilgarth

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

Marc Gravell
Marc Gravell

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

dkackman
dkackman

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

Jon Skeet
Jon Skeet

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

SirViver
SirViver

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

Related Questions