IList Sorting: A Better Way

David Mills

February 17, 2011

Programming forums across the web are replete with questions about how tosort an IList. Many .NET developers have discovered that, unlike List<T>, IList<T> does not define a Sort() method. Although there are many excellent answers to the question of how to sort an IList<T> on the forums, none of them are as convenient, elegant, and complete as they could be.

Breaking it Down.

First things first: How can we sort an IList<T>, anyway? Fortunately, we don't have to write our own sorting algorithm, since the .NET framework provides a way to get the job done. The ArrayList.Adapter method may be used to wrap the IList in an ArrayList, and then we can use the ArrayList's Sort() method on the wrapped list. This will have the effect of sorting the list in-place, without needing to make an in-memory copy.

ArrayList.Adapter(ilist).Sort( ... );

Defining the IList<T>.Sort() Extension Method

Since our goal is to mimic the List<T>.Sort() method, we must be able to accept a lamdba expression—in the form of a Comparison<T> delegate—into the Sort() method, like so:

We're almost there, but sadly, the extension method defined above will not compile. ArrayList.Sort() takes an IComparer, not a Comparison<T>. Our goal, however, is to accept a Comparison<T>, so how can we make that happen?

Wrapping the Comparison<T> Delegate

The answer is that we can wrap the Comparison<T> in a class implementing IComparer and IComparer<T>. We'll call the class ComparisonComparer, since it is an IComparer that works by using a Comparison<T> delegate.

Bonus: Enumerable<T>.OrderBy()

List.Sort() and ArrayList.Sort() are quick and easy to use, but they are both backed by the same implementation of the QuickSort algorithm in Array.Sort, which has one potential drawback: it's an unstable sorting algorithm. From MSDN:

[The Array.Sort] method uses the QuickSort algorithm. This implementation performs an unstable sort; that is, if two elements are equal, their order might not be preserved. In contrast, a stable sort preserves the order of elements that are equal.

The LINQ OrderBy() extension method provides an alternative way to sort a list, and utilizes a stable sorting algorithm. However, OrderBy() requires different syntax and will only accept a key selector delegate and/or an IComparer, rather than a Comparison<T>. Fortunately, the same technique that we used for IList<T> may be applied to OrderBy():

Using the New Extensions

There you have it! These extensions unify the syntax for several disparate sorting methods built-in to the .NET Framework. Simply include the SortExtensions classes in your project, and you can use a lambda expression (or other delegate) to easily sort ILists and IEnumerables: