Total votes: 0
Print: Print Article
Please login to rate or to leave a comment.
Published: 18 May 2011
Extension methods were new to C# 3.0. They allow you to add a method to an existing type without having to inherit from that type.
An extension method is a special kind of static method that is called as though it is a member of an existing type. They behave exactly as though they are a regular method and they even show up in Intellisense for the target type.
In fact, LINQ uses extension methods to add query functionality to the existing
IEnumerable<T> data types. These LINQ methods are available to any object that implements these types, even though the methods were not originally defined as part of those types.
It is very simple to create an extension method. They are mostly useful for quickly adding methods to existing types. For example, say your application has a handy routine that works with strings, and you find yourself calling that routine all the time. Extension methods allow you to easily write that routine as a method of the existing string class.
A Simple Example
So, let's get our hands dirty with a simple example. The string class is very handy, but it has no
Reverse() method. The following code adds an extension method that gives the string class this method.
There are a few things to point out in the code snippet above. First, notice that both the class and method are defined as static.
Also, notice the first argument to
Reverse() uses the keyword
this. In this case, this keyword indicates that the method is an extension method for the string class. You can add additional arguments but the first one identifies the method as an extension method and associates it with a particular type.
As long as the class above is visible to your code, you can then call the
Reverse() method as though it's a regular method of the string class.
And since C# lets you box string constants, you can also call the new method like this.
Note that extension methods are also available to all types that derive from the target type. You could even add an extension method to the
object type. Since all classes derive from
object, your extension method would then be available to all classes. Of course, just because you can do something doesn't necessarily mean it's a good idea.
No State Management
There are a couple of limitations to extension methods. For example, they can't hold instance variables to manage state information. Consider the extension method below, which parses a token from a string.
If this method was part of a regular class, you'd probably want to add the ability for the class to track the current position within the string being parsed. As a result, the calling code wouldn't need to track this information. This is a fundamental benefit of OOP programming in general, and is why code written using classes tends to be easier to use than code written without them.
However, in the case of an extension method, we don't have that option. There is no place we can store information such as the current position within the string being parsed. Instead, the calling code must keep track of and provide any state information. This is not a big deal, but it can result in slightly more effort being required to write the code that calls an extension method.
The following code uses the
ParseToken() extension method defined above to parse all the words in a string.
Just for fun, let's look at one more example. The following code adds two extension methods to the
Dictionary<string, string> class. The
Load() extension methods add the ability to save the contents of the dictionary to a file, and read it back again.
The contents are stored in a human-readable text format. This makes it easy to edit these files. Each value within the dictionary is stored on a single line using the key, followed by the equal sign (=), followed by the value.
Note that, in order to keep things simple, this extension method is limited only to
Dictionary collections where both the key and value types are
string. You could certainly write extension methods to support other collection types. Hopefully, this gets you thinking about some of the useful ways that you can use extension methods.
To use this code, simply declare an instance of the
Dictionary<string, string> class. Ensure that the class above is "visible" from your calling code, and call the new
Load() methods with the name of the file.
What could be easier than syntactically associating a method that works with strings with the
string class? Or to have a method that saves a collection to disk appear as a method of that collection class? It's a lot easier to find helper methods when they appear as part of the type they operate on, especially when they show up in Intellisense.
For these reasons, I actually think extension methods are pretty cool. To be sure, they can be abused. But they provide a powerful technique to add new methods to existing types.
Of course, you do have other options. You could also inherit from an existing class and add methods in your inherited class. This would also give you the ability to track state information. However, extension methods give you a bit more flexibility because they can be applied to classes already being used by your code. If you created a new class, you may need to change your existing code.
Either way, it's good to have an understanding of extension methods so you can put them to work where they make good sense.
Jonathan developers software and websites from home in the Salt Lake City, UT area. He hikes each week with his German Shepherd Dog, Suki.
This author has published 2 articles on DotNetSlackers. View other articles or the complete profile here.
Please login to rate or to leave a comment.