Click here to Skip to main content
11,705,212 members (51,238 online)
Click here to Skip to main content

How To Use Extension Methods

, 25 Oct 2007 CPOL 27.9K 139 41
Rate this:
Please Sign up or sign in to vote.
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.

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:

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.

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.

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:

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:

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

which can be translated to using extension methods:

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:

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.

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)

Share

About the Author

Steve Hansen
President 2sky
Belgium Belgium
No Biography provided

You may also be interested in...

Comments and Discussions

 
Generalnice on Pin
Pranay Rana30-Dec-10 0:05
memberPranay 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
memberAlexis 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
memberSteve Hansen8-Jun-08 22:08 
GeneralI liked it Pin
Johan Fourie30-Oct-07 13:47
memberJohan Fourie30-Oct-07 13:47 
GeneralRe: I liked it Pin
Steve Hansen30-Oct-07 15:37
memberSteve Hansen30-Oct-07 15:37 
GeneralA bit confusing Pin
WillemM25-Oct-07 1:42
memberWillemM25-Oct-07 1:42 
GeneralRe: A bit confusing Pin
Steve Hansen25-Oct-07 2:25
memberSteve Hansen25-Oct-07 2:25 
GeneralRe: A bit confusing Pin
WillemM25-Oct-07 3:47
memberWillemM25-Oct-07 3:47 
GeneralRe: A bit confusing Pin
Ben Daniel25-Oct-07 15:35
memberBen Daniel25-Oct-07 15:35 
GeneralRe: A bit confusing Pin
Steve Hansen25-Oct-07 20:19
memberSteve Hansen25-Oct-07 20:19 
GeneralRe: A bit confusing Pin
brian_agnes31-Oct-07 5:17
memberbrian_agnes31-Oct-07 5:17 
GeneralRe: A bit confusing Pin
Steve Hansen31-Oct-07 5:25
memberSteve Hansen31-Oct-07 5:25 
GeneralRe: A bit confusing Pin
pjd10014-Nov-07 14:48
memberpjd10014-Nov-07 14:48 
GeneralI like your article Pin
HummerX9-Dec-07 17:28
memberHummerX9-Dec-07 17:28 
GeneralRe: I like your article Pin
Steve Hansen9-Dec-07 20:29
memberSteve Hansen9-Dec-07 20:29 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150819.1 | Last Updated 25 Oct 2007
Article Copyright 2007 by Steve Hansen
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid