IComparable
only works one way
Let's say you have a Employee
class. In one view, you want to show all Employees
sorted by name - in another, by address. How are you going to achieve that? Not with IComparable
, at least not in any idiomatic way.
IComparable
has the logic in the wrong place
The interface is used by calling .Sort()
. In a view showing Customer
sorted by name, there is no code at all to implicate how it is going to be sorted.
On the other hand, the Customer
class is assuming how it is going to be used - in this case, that it will be used in a list sorted by names.
IComparable
is used implicitly
In comparison with the alternatives, it is very difficult to see where the comparing logic is being used - or if at all. Assuming your standard IDE and starting from the Customer
class, I will have to
- Search for all references to
Customer
- Find those references which are used in a list
- Check if those lists ever have
.Sort()
called on them
What's probably worse, if you remove an IComparable
implementation that is still being used, you get no error or warning. The only thing you will get is wrong behaviour in all places that were too obscure for you to think of.
These issues combined, plus changing requirements
The very reason I came to think about this is because it went wrong for me. I have been happily using IComparable
in my application for 2 years now. Now, the requirements changed and the thing needs to be sorted in 2 different ways. It have noticed that it is no fun going through the steps described in the previous section.
The question
These issues make me think of IComparable
as inferior to IComparer
or .OrderBy()
, to the point of not seeing any valid use case that wouldn't be served better by the alternatives.
Is it always better to use IComparer
or LINQ, or are there advantages/use cases I am not seeing here?
IComparable
anymore, which is reinforcing my point.SortedXXX
collections, they either require the stored elements to beIComparable
or to have aIComparer
provided. Also note, that it is trivial to reverse the natural sort order with one comparer and have it work with allIComparable
objects.IComparable
is considered the default comparison mechanism.IComparer
is used when you want to override the default comparison mechanism.ReverseComparer<T>
: gist.github.com/jackfarrington/078e7af7bc82482aa634