Published

C# 3.0 – Extension Methods

Extension methods are a very cool feature. They are special static methods that can be used as if they were instance methods. What does it mean from our developer perspective? That we can simulate we add new methods to existing types.

It's quite common to find an existing class we want to extend with some new features. The alternatives to extend a class in this situation are limited, normally we will inherit from the class we want to extend, we will use a decorator pattern over it or we will embed the class in a wrapper. These techniques can be very useful, but sometimes they are not exactly what we really want to do.

Let's say you want a method that allows you to sort an array of int descending, the easiest approach you probably will use is to create a static method SortDesc that receives an int array as parameter and contains the logic to sort the array. Something similar to:

1:staticvoid Main(string[] args)

2: {

3:

4:int[] numbers = newint[] { 1, 2, 3, 4, 5, 6 };

5:

6: SortDesc(numbers);

7:

8:foreach (int number in numbers)

9: {

10: System.Diagnostics.Debug.WriteLine(number);

11: }

12: }

13:

14:publicstaticvoid SortDesc(int[] numbers)

15: {

16:if (numbers != null && numbers.Length > 1)

17: {

18:bool sorted;

19:do

20: {

21: sorted = true;

22:for (int i = 0; i < numbers.Length; i++)

23: {

24:if (i < numbers.Length - 1 && numbers[i] < numbers[i + 1])

25: {

26:int tmp = numbers[i];

27: numbers[i] = numbers[i + 1];

28: numbers[i + 1] = tmp;

29:

30: sorted = false;

31: }

32: }

33: } while (!sorted);

34: }

35: }

With extension methods, we can rewrite the code in a way that the call to SortDesc is done as any other method of the class int[], like GetLength or GetLongLength. To do it we need we just need to apply the right syntax.

To declare an extension method we need include them in a static class, to specify the type we are going to extend we should set the modifier "this" before the first parameter of the method, being the type of the first parameter the type we are extending, in our case int[]. Once this is done we only need to import the namespace where we have created the static class, and all the int[] variables we use in the context will benefit of our new SortDesc method, and the coolest thing is that we will have intellisense for them. Look the code below.

1:using Blog.Utilities;

2:

3:staticvoid Main(string[] args)

4: {

5:int[] numbers = newint[] { 1, 2, 3, 4, 5, 6 };

6:

7:// New method invoke!!!

8: numbers.SortDesc();

9:

10:// Traditional method invoke!!!

11: Extensions.SortDesc(numbers);

12:

13:foreach (int number in numbers)

14: {

15: System.Diagnostics.Debug.WriteLine(number);

16: }

17: }

18:

19:namespace Blog.Utilities

20: {

21:// Static class

22:publicstaticclass Extensions

23: {

24:// Note the "this" modifier before the parameter

25:publicstaticvoid SortDesc(thisint[] numbers)

26: {

27:// Method body

28: }

29: }

30: }

If you look the line 11 you can see that the old syntax can be used to invoke the method, in fact the IL code generated proves that the compiler just translates the new invocation to the old one.

The last thing we must know about Extension Methods is that their visibility is lower than instance methods, this means that if we have an instance method and an extension method, with the same parameters for the same type, the instance method will have preference over the extended one.