Hi

In my previous article I talked about why SortedList is not a good option to use if you need a sorted collection with keys that are not unique. Today I will show you how to use a regular generic List<T> to store sorted items. You basically have 2 options.

IComparable Interface

this means that you will have to make your stored class Implement the IComparable Interface. Here is an example:

   1: public class data : IComparable
   2:         {
   3:             public int A { get; set; }
   4:             public string B { get; set; }
   5:  
   6:             #region IComparable Members
   7:  
   8:             public int CompareTo(object obj)
   9:             {
  10:                 data comparable = obj as data;
  11:                 if (A == comparable.A)
  12:                 {
  13:                     return 0;
  14:                 }
  15:                 else
  16:                 {
  17:                     if (A > comparable.A)
  18:                     {
  19:                         return 1;
  20:                     }
  21:                     else
  22:                     {
  23:                         return -1;
  24:                     }
  25:                 }
  26:             }
  27:             #endregion
  28:         }

The implementation of IComparable is similar to the StringCompare one. if equal return 0, if bigger then return 1 and if smaller then return -1. Which helps us get rid of the If, Else and implement it like this:

   1: public class data : IComparable
   2:         {
   3:             public int A { get; set; }
   4:             public string B { get; set; }
   5:  
   6:             #region IComparable Members
   7:  
   8:             public int CompareTo(object obj)
   9:             {
  10:                 data comparable = obj as data;
  11:                 return A - comparable.A;
  12:             }
  13:  
  14:             #endregion
  15:         }

the program from the last post will look like this:

   1: static void Main(string[] args)
   2:         {
   3:             //SortedList<int, string> list = new SortedList<int, string>();
   4:             List<data> list = new List<data>();
   5:             data one = new data() { A = 1, B = "One" };
   6:             data two = new data() { A = 2, B = "Two" };
   7:             data three = new data() { A = 3, B = "Three" };
   8:             data four = new data() { A = 4, B = "Four" };
   9:             list.Add(two);
  10:             list.Add(one);
  11:             list.Add(four);
  12:             list.Add(three);
  13:             list.Sort();
  14:             foreach (data s in list)
  15:             {
  16:                 Console.WriteLine(s.B);
  17:             }
  18:             Console.ReadLine();
  19:         }

And the output will be sorted after calling to List.Sort() on line 13. This way no matter how complicated you class is you can implement the comparison yourself and get the results you want.

Using Comparer

A Comparer is a class that derives from Comparer<T> abstract class and has one method to override "int Compare(T1,T2)". For this example we will use the same dataclass but we will not implement the IComparable Interface. Data class looks like this:

   1: public class data 
   2:         {
   3:             public int A { get; set; }
   4:             public string B { get; set; }
   5:         }

We need to implement a new class that will ace as the Comparer:

   1: public class DataComparer : Comparer<data>
   2: {
   3:     public override int Compare(data x, data y)
   4:     {
   5:         return x.A - y.A;
   6:     }
   7: }

All we have to do is to replace List.Sort() (Line 13) with:

   1: list.Sort(new DataComparer());

And that is it, your list is sorted.

The hardest question is which one to choose. We know it is better than SortedList that is for sure…

I don’t yet know of any downfalls to anyone of them but I personally prefer the first one.

Tell me what you think and dont forget to read the previouse article about SortedList

Amit

Tags :

7 Responses to “List.Sort(), Comparer and IComparable”


  1. wwfDev

    Said on July 11, 2008 :

    I’m lazy and always ends up using anonymous methods rather than comparer classes:

    myList.Sort(delegate (MyItem x, MyItem y)
    {
    return x.A.CompareTo(y.A);
    });

  2. Amit

    Said on July 11, 2008 :

    I thought about using anonymnous delegates but I dont like using them unless I have to “steal” a local variable, it is a great thing but it tends to make code unreadable in my opinion.

  3. Damian

    Said on July 11, 2008 :

    I reckon that if you are going to reuse the DataComparer class more than once in different places, then the anon method is the way to go. There is definitely a readabilty speed bump when it comes to anonymous methods, lamdas and the like, especially when debugging and stepping through code, but once you’ve got it, it’s just lovely!

  4. André Matter

    Said on August 23, 2010 :

    Muito Obrigado! Muito esclarecedor o método de utilização de Comparer!

  5. André Matter

    Said on August 23, 2010 :

    Thank you very much!
    That´was real helpfull the explanation about how to use the Comparer Class, it helped me a lot!

    André Matter, Brazil.

  6. Anton

    Said on September 23, 2011 :

    I’m lazy too:)

    myList.Sort((x, y) => x.A.CompareTo(y.A));

1 Trackback(s)

  1. Jul 13, 2008: Weekly Link Post 50 « Rhonda Tipton’s WebLog

Post a Comment