Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Extension Methods Exemplified: Sorting Index-based Generic Lists

5.00/5 (9 votes)
23 Aug 2008CPOL2 min read 1   162  
This article shows how extension methods can be used, e.g., for sorting index-based generic lists.

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:

C#
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:

C#
IList<int> list = new int[10] {3 , 5 , 8 , 6 , 7 , 6 , 2 , 1 , 9};
list.Sort(); //Compiler error, for IList<T> doesn't possess a method 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:

C#
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
        {
            //This extension method is visible where the namespace
            //Extensions is brought into scope

            Sort(list, 0, list.Count - 1);
        }

        public static void Sort<T>(this IList<T> list, 
               int startIndex, int endIndex) where T : IComparable
        {
            //This extension method is visible where the namespace
            //Extensions is brought into scope

            //Bubble Sort
            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)
        {
            //This extension methods is only visible within SortingExtensionsProvider

            T tmp = list[index1];
            list[index1] = list[index2];
            list[index2] = tmp;
        }

        private static bool IsLesserThan(this IComparable value, IComparable item)
        {
            //This extension method is only visible within SortingExtensionsProvider

            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):

C#
using Extensions;
...
IList<int> list = new int[10] {3 , 5 , 8 , 6 , 7 , 6 , 2 , 1 , 9};
list.Sort(); //Extension method

History

  • Update: July 25, 2008
  • Update: August 1, 2008
  • Update: August 23, 2008

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)