Deep Dive on Extension Methods
Microsoft C# MVP
This article provides information about a new feature of C# 3.0 called Extension Methods. Extension Methods allow developers to add new methods to an existing type without having to create an inherited class or to recompile the original. This concept allows you to add methods to classes for which you might not even have the sources; e.g., System.String.
Since extension methods might be complex to understand, so let’s see a traditional example first. Take a look at this simple program:
Although this works fine, the code is hard to read because it calls a static method which stands in a static class.
To simplify this code, we can use the Extension Methods available with C# 3. Take a look at the same application, rewritten with C# 3 and Extension Methods:
If you execute this application, you will see that the result is the same (the string is returned in uppercase) but the code is more intuitive and comprehensive than the previous version.
Before trying to understand how to implement an Extension Method, let’s use Reflector to take a look at the MSIL that the second example produces:
As you can see, the call to the Extension Method is translated, in IL (Intermediate Language), into a call to a simple static method. What does this mean? Simply that Extension Methods are nothing more than an easier way to call static methods, allowing you to write code that is more intuitive.
We can see that the code for our Extension Method has been translated during compilation into a static method with a specific attribute (ExtensionAttribute) enabling the compiler to understand that this method is, in fact, an Extension Method:
As with static methods, the validity of an Extension Method is tested during compilation. If, when compiling, the Extension Method is not found, you will receive an error message like this one:
“’string’ does not contain a definition for ‘StringToUpper’ and no extension method‘StringToUpper’ accepting a first argument of type ‘string’ could be found”:
As we have seen, Extension Methods are used in the same way as other instance methods. So how can you differentiate an Extension Methods from a “normal” method? Well, Visual Studio 2008 will help you in this task.
Indeed, Intellisense in Visual Studio 2008 has been improved to indicate to developers which kind of methods they are using. Thus, if you use Intellisense to display the list of all the methods and properties available for an object, you should be able to see something like this:
An Extension Method is distinguished by:
· A little blue arrow
· The text of the tooltip, which contains the string “(extension)”
Now that we have seen how Extension Methods work, let’s take a better look at the correct way of using this new feature in your projects.
To understand how to implement an Extension Method, let’s revisit our example:
An Extension Method is defined by several rules:
· The method is defined in a non-generic static class that is not nested.
· The method itself is static.
· The first parameter of an Extension Method is preceded by the modifier this. This parameter is called an “instance parameter” and can only appear as the first parameter of the method.
· No other parameter modifiers (ref, out, etc…) are allowed with the modifier this. As a result, a value type can’t be passed by reference to an Extension Method.
· The instance parameter cannot be a pointer type.
· The method must be public, internal or private: it's a stylistic choice to declare them public, but not a requirement!
· Extension Methods are in a namespace which is in scope.
If your method successfully matches all these points, you can safely say that it’s an Extension Method!
If your Extension Method is in another namespace (or another DLL), you will need a using statement to import the content of this namespace and make the call of your method possible:
LINQ (Language Integrated Query) is a new technology for querying objects, XML and SQL. It uses Extension Methods a lot. If you have already written LINQ code, you may have used these methods without knowing what kind of methods they were:
All the methods shown in this IntelliSense window reside in the namespace “System.Linq”, which is found in the assembly “System.Core.dll”. Take a look at this listing of the System.Linq.Enumerable class created inside Visual Studio 2008 from metadata:
About the author:
Thomas Lebrun currently works as a consultant and trainer at Winwise ( http://www.winwise.fr). Since July 2007, he’s a Microsoft C# MVP for his work on C# and WPF. You can find his blog at http://blogs.developpeur.org/tom.