Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IComparable and IComparable<T>

Should I implement both IComparable and the generic IComparable<T>? Are there any limitations if I only implement one of them?

like image 313
Mark Menchavez Avatar asked Sep 04 '11 18:09

Mark Menchavez


2 Answers

Yes, you should implement both.

If you implement one, any code that depends on the other will fail.

There is lots of code that uses either IComparable or IComparable<T> but not both, so implementing both ensure your code will work with such code.

like image 196
Oded Avatar answered Oct 01 '22 05:10

Oded


Oded is right that you should implement both because there are collections and other classes that rely on only one of the implementations.

But there is a trick there: IComparable<T> should not throw exceptions, while IComparable should. When implementing IComparable<T> you are in charge to ensure that all instances of T can be compared against each others. This includes null, as well (treat null as smaller than all non-null instances of T and you'll be fine).

However, general IComparable accepts System.Object and you can't guarantee that all conceivable objects would be comparable against instances of T. Therefore, if you get a non-T instance passed to IComparable, simply throw the System.ArgumentException. Otherwise, route the call to the IComparable<T> implementation.

Here is the example:

public class Piano : IComparable<Piano>, IComparable {     public int CompareTo(Piano other) { ... }     ...     public int CompareTo(object obj)     {          if (obj != null && !(obj is Piano))             throw new ArgumentException("Object must be of type Piano.");          return CompareTo(obj as Piano);      } } 

This example is part of a much longer article which contains extensive analysis of side-effects that you should take care of when implementing IComparable<T>: How to Implement IComparable<T> Interface in Base and Derived Classes

like image 41
Zoran Horvat Avatar answered Oct 01 '22 04:10

Zoran Horvat