Click here to Skip to main content
16,018,460 members
Articles / Programming Languages / C#
Article

How To Use Extension Methods

Rate me:
Please Sign up or sign in to vote.
3.64/5 (13 votes)
25 Oct 2007CPOL3 min read 44.5K   163   41   15
Explains how extension methods work and how you can use them.
Extension Method Intellisense

Introduction

This article will try to explain what extension methods are and how you can use them for your own application.

Background

Every static helper class can be converted to extension methods, so only basic knowledge of classes in .NET is required.

Using the Code

This article uses Visual Studio 2008. Although Visual Studio 2005 also allows you to use the .NET 3.5 features, its intellisense support isn't that great. For most of the code it shouldn't be a problem to use it in Visual Studio 2005.

The Problem

If you ever wanted to add extra functionality to an existing class, if you were lucky and the class wasn't sealed, you could override it and add the extra method. This wasn't always what you wanted, and sometimes it's not possible at all.

Take an interface for example, IEnumerable<T>, what do we know about it?
The MSDN description is:
Exposes the enumerator, which supports a simple iteration over a collection of a specified type.
So every collection should implement this interface, it doesn't matter if it's a list or an array, we only know that we can get the elements back.

The Solution

We have declared an array of strings to work with.

C#
string[] strings = new string[] { "Green", "Yellow", "Red", "Blue" };

So let's say we want the last element of this IEnumerable<T>.

Writing code to solve these problems in .NET 2.0 would require static helper methods, we could solve it with this simple helper method:

C#
public static class EnumerableHelpers
    {
        public static T Last<T>(IEnumerable<T> enumerable)
        {
            if (enumerable == null)
            {
                throw new ArgumentNullException("enumerable");
            }
            // We know we can foreach through it
            T last = default(T);
            foreach (T item in enumerable)
            {
                last = item;
            }
            return last;
        }
    }

We could also add some typechecking on IList but this sample will always work. If the IEnumerable was empty, it would return the default value for T, null for classes and 0 for int etc.
The code is also easy to use and can be used on any enumerable.

C#
string last = EnumerableHelpers.Last(strings);

The compiler knows which generic type to use so we don't have to write Last<string>. But it doesn't look as good as being able to type strings.Last().

Now the only thing we need to change is add the special keyword for an extension method which is this before the first parameter. And it always has to be the first parameter.

C#
public static class EnumerableHelpers
    {
        public static T Last<T>(this IEnumerable<T> enumerable)
        {
            if (enumerable == null)
            {
                throw new ArgumentNullException("enumerable");
            }
            // We know we can foreach though it
            T last = default(T);
            foreach (T item in enumerable)
            {
                last = item;
            }
            return last;
        }
    }

With this change, the compiler knows it can use this method on any IEnumerable<T> and will even show intellisense for it.

Our custom extension method

Our last code sample can now be defined as:

C#
string last = strings.Last();

which makes it seem like it is just a method of IEnumerable<string>.

Usage In .NET 3.5

All these extension methods for any Enumerable are already implemented with .NET 3.5 and are the basics for LINQ.
It doesn't matter if it's a List or an Array or any other collection. It just matters that it supports the IEnumerable<T> interface.
The only extra that you get is another new syntax to call them like this one:

C#
IEnumerable<int> result = 
    from s in strings where s.Length > 4 select s.Length;

which can be translated to using extension methods:

C#
IEnumerable<int> result2 = 
    strings.Where(s => s.Length > 4).Select(s => s.Length);

Another new feature that shows up here are lambda expressions, they won't be explained here maybe some other time.
You could easily rewrite them to be more .NET 2.0 by using anonymous delegates:

C#
IEnumerable<int> result3 = 
    strings.Where(delegate(string s) 
    { return s.Length > 4; }).Select(delegate(string s) 
    { return s.Length; });

Almost there now, we could also get rid of the extension methods completely.

C#
IEnumerable<int> result4 = 
    Enumerable.Select(Enumerable.Where(strings, delegate(string s) 
    { return s.Length > 4; }), delegate(string s) { return s.Length; });

If you see what is translated for this small LINQ query (just a simple where and select), you can imagine what it'll do when you start creating more complex queries.

Conclusion

Extension methods are very easy to use and when used properly will make your code much more readable. They can be used on anything (Classes, Interfaces, Structs, Enums, ...) which makes them a powerful tool.

The included source code has the code snippets that are used in this article and some other extension methods that you can use.

History

  • October 25, 2007: First version

License

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


Written By
President 2sky
Belgium Belgium
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Generalnice on Pin
Pranay Rana30-Dec-10 0:05
professionalPranay Rana30-Dec-10 0:05 
Questionwhat are the risks when extending an established core class with additional methods Pin
Alexis Rzewski7-Jun-08 1:24
Alexis Rzewski7-Jun-08 1:24 
AnswerRe: what are the risks when extending an established core class with additional methods Pin
Steve Hansen8-Jun-08 22:08
Steve Hansen8-Jun-08 22:08 
That's why Microsoft recommends to put extensions in a separate namespace. This way you can choose easily which extensions to include.

My article just tries to explain what they are and how they are used in the .NET framework (for example with LINQ).

I do understand your point, but I think that a few good extensions can improve readability and the overall code.

Btw, a wrapper could easily solve your last problem Smile | :)

As always, prefer composition above inheritance Wink | ;)
GeneralI liked it Pin
Johan Fourie30-Oct-07 13:47
Johan Fourie30-Oct-07 13:47 
GeneralRe: I liked it Pin
Steve Hansen30-Oct-07 15:37
Steve Hansen30-Oct-07 15:37 
GeneralA bit confusing Pin
WillemM25-Oct-07 1:42
WillemM25-Oct-07 1:42 
GeneralRe: A bit confusing Pin
Steve Hansen25-Oct-07 2:25
Steve Hansen25-Oct-07 2:25 
GeneralRe: A bit confusing Pin
WillemM25-Oct-07 3:47
WillemM25-Oct-07 3:47 
GeneralRe: A bit confusing Pin
Ben Daniel25-Oct-07 15:35
Ben Daniel25-Oct-07 15:35 
GeneralRe: A bit confusing Pin
Steve Hansen25-Oct-07 20:19
Steve Hansen25-Oct-07 20:19 
GeneralRe: A bit confusing Pin
brian_agnes31-Oct-07 5:17
brian_agnes31-Oct-07 5:17 
GeneralRe: A bit confusing Pin
Steve Hansen31-Oct-07 5:25
Steve Hansen31-Oct-07 5:25 
GeneralRe: A bit confusing Pin
urbane.tiger4-Nov-07 14:48
urbane.tiger4-Nov-07 14:48 
GeneralI like your article Pin
HummerX9-Dec-07 17:28
HummerX9-Dec-07 17:28 
GeneralRe: I like your article Pin
Steve Hansen9-Dec-07 20:29
Steve Hansen9-Dec-07 20:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.