Introduction and Background
Since the .NET Framework 3.0, the developer has an interesting tool to enable him to add methods to already existing types without deriving or recompiling it. For example, the LINQ standard operators that add query functionality to the interfaces System.Collections.IEnumerable
and System.Collections.IEnumerabley<T>
make use of this concept, which is called Extension Methods. Thus, any type implementing one of these interfaces seems to have instance methods such as GroupBy
, Where
, etc., albeit these are only extensions to them and are not to be found in the respective original type implementations.
Extension Methods are static methods that can be invoked by using the instance method syntax. They make it possible to extend existing types with additional methods.
This article shows how this concept can be used to sort index-based generic lists.
Sorting Generic Index-based Lists
When you browse the instance methods of the types System.Array
, System.Collections.ArrayList
, and System.Collections.Generic.List<T>
, you can find a method Sort
. Hence, sorting a list of one of these types is easy:
ArrayList list = new ArrayList() {3 , 5 , 8 , 6 , 7 , 6 , 2 , 1 , 9};
list.Sort();
Observing the other index-based collections, however, you will miss a sorting method. Since every index-based collection implements System.Collections.Generic.IList<T>
, a call similar to that above would fail:
IList<int> list = new int[10] {3 , 5 , 8 , 6 , 7 , 6 , 2 , 1 , 9};
list.Sort();
So, you would either have to convert your collection to one of the appropriate collection types above, or implement your own sorting algorithm. And, here comes the concept of Extension Methods into play. Instead of simply implementing a method that takes an IList<T>
as its parameter, you could better create an extension method that applies to every IList<T>
-implementing type, and can then be used as in just the same way as in the ArrayList
example.
Extension Methods are implemented in a static
class. It is important that an extension method has the modifier this
, followed by the type which you want to extend as its first parameter.
Example Code
In this example, I implemented the Bubble Sort algorithm:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Extensions
{
public static class SortingExtensionProvider
{
public static void Sort<T>(this IList<T> list) where T : IComparable
{
Sort(list, 0, list.Count - 1);
}
public static void Sort<T>(this IList<T> list,
int startIndex, int endIndex) where T : IComparable
{
for (int i = startIndex; i < endIndex; i++)
for (int j = endIndex; j > i; j--)
if (list[j].IsLesserThan(list[j - 1]))
list.Exchange(j, j - 1);
}
private static void Exchange<T>(this IList<T> list, int index1, int index2)
{
T tmp = list[index1];
list[index1] = list[index2];
list[index2] = tmp;
}
private static bool IsLesserThan(this IComparable value, IComparable item)
{
return value.CompareTo(item) < 0;
}
}
}
Be aware that the private
methods Exchange<T>
and IsLesserThan
are extension methods, too, but they are only visible in the class SortingExtensionProvider
.
Now, if you bring the namespace Extensions
into scope by the using
directive, IList<T>
will have an additional method Sort
(to be exact: two of them):
using Extensions;
...
IList<int> list = new int[10] {3 , 5 , 8 , 6 , 7 , 6 , 2 , 1 , 9};
list.Sort();
History
- Update: July 25, 2008
- Update: August 1, 2008
- Update: August 23, 2008