Click here to Skip to main content
15,881,455 members
Articles / Programming Languages / C#

Internals of Extension Methods

Rate me:
Please Sign up or sign in to vote.
4.80/5 (12 votes)
16 Mar 2011CPOL5 min read 19.5K   9   7
Internals of Extension Methods

Introduction

It is nice to see that people like my post so much. Ever since I wrote about “Internals of Delegates”, there are large number of hits on my site and people wanted me to continue posting few more internals like that. Even I was thinking the same, I was confused about what I should start for my next topic. Finally, I have decided to speak about another important C# feature that we use very often called Extension methods and try to look deep into its facts. Let's first demonstrate the basics of Extension methods first and later we will dive deep into it. If you are comfortable with Extension methods, please skip the following section.

The Basics

Extension method is actually defined as static but acts as an instance specific method. In other words, even though the code that is running inside the Extension method is not declared within the scope of the class, it is still associated with an instance of an object for that particular class. Extension method does not need to be in the same namespace where the actual type is. Hence you can easily add extension method anywhere outside the namespace and any other static class. The namespace which when added to the code will automatically add those extension methods and call appropriately for an existing type. Extension methods can also be thought as extension to a pre-existing type.

For instance, let me define a class first:

C#
public class MyClass
{
    public int MyMethod()
    {
        Random rand = new Random(100);
        return rand.Next();
    }
}

This is a very simple class with one method MyMethod which returns an integer value. Now how to extend the class to add another method say MyMethod2. There are a couple of option available for you, either you need to extend this class to another type MyClass2 derived from MyClass and include that method into it, or use extension method to add it directly within the type MyClass itself.

C#
public static class Extensions
    {        
        public static int MyMethod2(this MyClass obj)
        {
            return 10;
        }
    }

MyMethod2 is now an extension method which is included with MyClass. You should remember that Extension method is static with the first argument being of Type in which the method is to be included with a “this” keyword in front of it. This identifies it as an extension method. Any parameter can be passed normally after the first argument.
By the way, you can even make MyClass sealed (not extensible), yet you have the option to use extension method to extend the type.

Note: By using extension method you can extend any type, even from the BCL.

Calling an Extension Method

Well, there is nothing as simple as we could speak about calling an extension method. There is no extra thing that you need to do when you call an extension method. Extension method is called just the same way as you call a normal instance method. The compiler automatically replaces the call to provide appropriate method binding.

C#
MyClass tobj = new MyClass();
    Console.WriteLine("Value from Instance method : {0}",tobj.MyMethod());
    Console.WriteLine("Value from Extension method : {0}", tobj.MyMethod2());
    Console.Read();

You can even add extension method to any known Types.

C#
public static byte[] GetBytes(this string thestring)
{
    return Encoding.ASCII.GetBytes(thestring);
}

Here every string you declare will automatically add GetBytes method into it.

Internals of Extension Method

Now as you know the basics of Extension methods, let's go a little depth. The first thing that I would like to share with you is how a method is actually called in IL for extension method.

C#
MyClass tobj = new MyClass();

tobj.MyMethod();
tobj.MyMethod2();
Extensions.MyMethod2(tobj);

Now let us look into three calls in IL.

So if you demonstrate the three lines in IL, it is evident that the last two calls are exactly the same while the first is instance specific call. The C# compiler translates the call exactly the same way as if we call the static method directly. The first call is the general call to the MyMethod member, which uses callvirt (to ensure it is latebound) while the next two methods invokes a call (strictly compile time bound).

So what is the main advantage of having extension method then if it produces the same MSIL as if we do call it normally? Is there any specific advantage we get if we create an extension method ? Let's demonstrate the IL for Extensions class.

We put two methods in Extensions class, such that the class looks like:

C#
public static class Extensions
    {   
        public static int MyMethod1(MyClass obj)
        {
            return 10;
        }
        public static int MyMethod2(this MyClass obj)
        {
            return 10;
        }
    }

So the MyMethod1 is the same replica to MyMethod2, the only difference is that MyMethod2 is an extension method. Now if you dissemble the code, it will look like:

You should notice, in the actual IL, the only thing that differentiates between the two methods is the presence of ExtensionAttribute in MyMethod2. MyMethod2 creates an object of custom ExtensionAttribute class.

So you should be clear, the compiler just puts an ExtensionAttribute to both the class and the Extension method and the code that I think might produce this IL would look like:

C#
[Extension]
    public static class Extensions
    {   
        public static int MyMethod1(MyClass obj)
        {
            return 10;
        }
        
        [Extension]
        public static int MyMethod2(MyClass obj)
        {
            return 10;
        }
    }

Strange rules to the compiler, C# gives you an error saying you should not use Extension attribute, rather use this syntax instead.

Now as we get through with this, let's demonstrate the power of the compiler while translating the Extension methods into IL. Let me cast the method into a delegate.

C#
Func<int> action = tobj.MyMethod2;
object t = action.Target;
Console.WriteLine(t);

If you see the output to this, its MyClass rather than null. Now let's see how IL looks like:

Again, this is very unnatural. The compiler again writes this for us. The delegate Func receives the object as first argument (as Target). Hence the Target for extension method behaves appropriately (as instance method). Neato!!!

[Note: Does it relates to Adapter Pattern?]

Just few minutes back Zenwalker asked me about the relationship between Adapter pattern and Extension Methods. Well, in fact I think there is no relation between the two, even though both creates Type wrappers. Adapter pattern being a design pattern introduces Wrappers to make one type compatible with another using a common interface between the two; While Extension methods is language feature and it allows a type to extend its hierarchy.

Conclusion

That’s all, folks. Even though I tried a little more to check MethodInfo.GetCurrentMethod() it seems to be nothing to talk about. Extension method is a language feature (not a CLI change) and the Microsoft guys did great to make it more useful. I liked it.

Thanks for reading.

License

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


Written By
President
India India
Did you like his post?

Oh, lets go a bit further to know him better.
Visit his Website : www.abhisheksur.com to know more about Abhishek.

Abhishek also authored a book on .NET 4.5 Features and recommends you to read it, you will learn a lot from it.
http://bit.ly/EXPERTCookBook

Basically he is from India, who loves to explore the .NET world. He loves to code and in his leisure you always find him talking about technical stuffs.

Working as a VP product of APPSeCONNECT, an integration platform of future, he does all sort of innovation around the product.

Have any problem? Write to him in his Forum.

You can also mail him directly to abhi2434@yahoo.com

Want a Coder like him for your project?
Drop him a mail to contact@abhisheksur.com

Visit His Blog

Dotnet Tricks and Tips



Dont forget to vote or share your comments about his Writing

Comments and Discussions

 
QuestionVery nice Pin
BillW338-Jun-12 4:44
professionalBillW338-Jun-12 4:44 
GeneralMore Interesting Things Pin
Ian Good16-Mar-11 14:16
Ian Good16-Mar-11 14:16 
GeneralOMG - Many articles Pin
MihaiDanceu16-Mar-11 13:17
MihaiDanceu16-Mar-11 13:17 
GeneralRe: OMG - Many articles Pin
RigaJoo17-Mar-11 10:51
RigaJoo17-Mar-11 10:51 
GeneralMy vote of 5 Pin
Dalek Dave8-Feb-11 0:56
professionalDalek Dave8-Feb-11 0:56 
GeneralMy vote of 5 Pin
Abhijit Jana17-Jan-11 5:11
professionalAbhijit Jana17-Jan-11 5:11 
Great Share Abhishek.
GeneralRe: My vote of 5 Pin
Abhishek Sur19-Jan-11 9:42
professionalAbhishek Sur19-Jan-11 9:42 

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.