IComparable Interface

Overview

  • IComparable is required for sorting.
  • CompareTo is used for sorting, Equals is used to compare equality. (IEquatable interface)
    • Returns less than 0, 0 or greater than 0 to indicate how another object relates to the current one.

Good practice

  • For objects A, B and C, the following must be true:
  • A.CompareTo(A) is required to return zero.
  • If A.CompareTo(B) returns zero, then B.CompareTo(A) is required to return zero.
  • If A.CompareTo(B) returns zero and B.CompareTo(C) returns zero, then A.CompareTo(C) is required to return zero.
  • If A.CompareTo(B) returns a value other than zero, then B.CompareTo(A) is required to return a value of the opposite sign.
  • If A.CompareTo(B) returns a value x not equal to zero, and B.CompareTo(C) returns a value y of the same sign as x, then A.CompareTo(C) is required to return a value of the same sign as x and y.

Examples

Custom Sorting

struct MyPoint: IComparable
{
    private int _x;
    private int _y;
 
    public int X
    {
        get { return this._x; }
    }
 
    public int Y
    {
        get { return this._y; }
    }
 
    public MyPoint(int x, int y)
    {
        this._x = x;
        this._y = y;
    }
 
    #region IComparable Members
    public int CompareTo(object obj)
    {
        if (obj is MyPoint)
        {
            MyPoint other = (MyPoint)obj;
 
            if (this._x.CompareTo(other.X) == 0)
            {
                return this._y.CompareTo(other.Y);
            }
            else
            {
                return this._x.CompareTo(other.X);
            }
        }
        else
        {
            throw new NotSupportedException("obj is not a MyPoint");
        }
    }
    #endregion
}
List<MyPoint> list = new List<MyPoint>();
list.Add(new MyPoint(10, 5));
list.Add(new MyPoint(10, 2));
list.Add(new MyPoint(10, 3));
list.Add(new MyPoint(4, 1));
list.Add(new MyPoint(15, 1));
 
list.Sort();
 
foreach (MyPoint p in list)
{
    Console.WriteLine(p);
}
 
/*
Will Print:
(4, 1)
(10, 2)
(10, 3)
(10, 5)
(15, 1)
*/