Published: 21 Sep 2008
By: Dino Esposito

Dino Esposito talks about extension methods in .NET

Contents [hide]

Introduction

Which came first? Was it the egg or was it rather the chicken? You know, this is the canonical example of a sort of futile dilemma around the first case of a circular reference. Want another nice example of such a causality dilemma? Which came first, C# extension methods or LINQ?

Introduced with the .NET Framework 3.5, extension methods let you add new methods to an existing class. How is this different from using classic inheritance? There are two fundamental differences—one conceptual and one practical. Conceptually, extension methods differ from inheritance because you don’t need to create a new type and implement new methods. The existing class is just “extended” with a new set of methods. From a more practical perspective, extension methods allow you to add methods also to sealed and not further derivable classes.

It works more or less as with hair extensions. You take an existing type and just attach new methods to it, without defining a new class or recompiling.

Syntax-wise, an extension method is a static method defined in a static class. However, from the point of view of client code (be it C# or Visual Basic) an extension method is invoked as if it is an instance method actually defined in the type.

Extension Methods at a Glance

To define an extension method, you create a class with only static methods. The class can be placed in any namespace and be named at your leisure. Here’s the typical skeleton of an extension methods container.

How is the relationship between the list of methods and the original type established? Nothing in the previous code snippet leads to think that I’m going to add extension method to, say, the System.String class. Here’s how to add an extension method to the System.String class that attempts to return an integer if a string-to-integer conversion can be successfully performed.

As you can see, the syntax of an extension method is a slight variation of the syntax of a regular static method. The signature of the method features an extra keyword: this. Just the type name trailing the this keyword indicates the type being extended with the method. The parameter name, instead, specifies the formal name through which the developer can reference the current instance of the “base” type it extends.

In the preceding code, the method ToInt extends the type System.String. The new method returns any integer that can be converted from the current content of the string. The TryParse method is invoked on the Int32 type to ascertain this possibility. If the current string cannot be converted to an integer, the minimum integer is returned. Other options entail throwing an invalid cast exception or a custom type of exception. Figure 1 shows how IntelliSense in Visual Studio 2008 processes extension methods.

Figure 1: Extension methods are listed as regular methods except for a different icon and tooltip.

Extension methods are listed as regular methods except for a different icon and tooltip.

There’s no limitation to the number of extensions you can make to a type. Likewise, there are no constraints on the types you can extend with these extra methods—system types as well as custom types.

Both methods considered in the previous example do not need any extra argument to work. What if the method requires one or more parameters? Here’s another example:

The RightSubstring method works on System.String objects and returns the rightmost substring of the specified length. As you can see, the method is merely a shortcut to calling the regular Substring method with a given set of arguments.

The first argument you specify in the signature of the static method operating as an extension method indicates the instance being extended. Any other parameters that follow on the signature indicate the signature of the extender method. Based on the preceding definition, the type System.String is extended with a RightSubstring method with the following prototype:

As a developer, all you have to do is bring in the namespace (and the assembly) where extension methods are defined. For a caller, extension and regular instance methods are the same. As you’ll see in a moment, this is not entirely true for the CLR.

Purposes of Extension Methods

What’s the purpose of extension methods? When are they useful and when should you consider using them in your own applications? Extension methods are a nice feature to have in C# but probably not one that developers requested in a loud voice. If you need to extend a type with additional capabilities, the best thing you can do is still deriving a new type.

By deriving a new type from an existing one, you inherit all the public members and gain access to all protected members of the base type. You may take advantage of features in the base type specifically designed for inheritance, such as virtual methods. If you have reusability in mind, then inheritance is by all means the way to go. Inheritance is a more powerful (and to some extent delicate to manage) mechanism than extension methods.

Extension methods are a shortcut for all those situations when you need an extra functionality that is not available on the base class, and you have no source code available or the original is sealed. In these cases, extension methods come to the rescue. You sneakily add desired methods to a class without modifying the original source code or assembly.

Extension methods differ from classic inheritance for a number of reasons. First off, extension methods are invoked like instance methods but are not instance methods. This means, for example, that they cannot invoke any non-static methods, except those available on parameters. In other words, any piece of code that an extension method shares with the outside world has to be static. In addition, an extension method has no access to protected members of the type it extends and cannot override or shadow an existing method. By design, in fact, an extension method is never invoked if there’s a member in the extended type with the same name and signature.

Personally, I use extension methods quite sparingly and mostly when I need shortcuts and utilities such as a WordCount or RightSubstring method on a type such as the String type, sealed at the .NET Framework level. Put this way, reasonably, extension methods are nice to have but not patently useful. What’s the real reason of their introduction? Enter LINQ.

Extension Methods and LINQ

Extension methods exist because of the role they play in LINQ. Extension methods are used to add new capabilities to the IEnumerable and IEnumerable<T> types. Why did Microsoft opt for extensions instead of just adding new query methods to enumerable types? I can’t answer for Microsoft’s architects, but I like to think that the principle of Single Responsibility had some influence on the final decision. The IEnumerable type represents a collection of data; querying a collection is another matter. An API was needed to query collections in a unified manner. At the same time, this API had to be pluggable by developers using collections. Let’s consider the following fragment.

If you use IntelliSense on the variable coll, you see what’s in Figure 2.

Figure 2: An IEnumerable type through IntelliSense without LINQ extensions

An IEnumerable type through IntelliSense without LINQ extensions

As you can see, IntelliSense shows only instance method defined on the type. Now add an extra line of code to link LINQ to the project.

Using IntelliSense on the same variable produces radically different results, as you can see in Figure 3.

Figure 3: An IEnumerable type through IntelliSense with LINQ extensions

An IEnumerable type through IntelliSense with LINQ extensions

The same type now shows a number of extension methods with the connection established at the namespace level. The underlying type is the same—IEnumerable—and it didn’t undergo any change or modification. A bunch of extra features—logically related—can be added by the developer simply bringing in a given namespace (and related assemblies).

Extension methods are useful in scenarios where you need to opt-in a given feature but want it to stay away by default. And also you don’t want to change anything in the types being used—regardless of the fact they are built-in or custom types.

A trick at the level of the CLR was the only way to go, and that’s why extension methods were introduced. Extension methods find in LINQ their rationale, but they’re also a feature that can be helpful in other scenarios. That’s why you find them fully supported by C# and Visual Basic in the .NET Framework 3.5.

Compilers resolve calls to extension methods by binding to a static method. However, in case of ambiguity (for instance, another instance method is found with the same name and signature) extension methods are given the lowest priority.

Summary

Extension methods allow you to enrich the programming interface of a given class. The most interesting aspect of extension methods is that you don’t use a new type, but stick to the old type just “enriched” with new methods. Extension methods are not like inheritance and do not compete with inheritance. They are an “internal” framework feature promoted to the rank of a public feature. Extension methods have been introduced to enrich the IEnumerable interface for LINQ purposes; that is the scenario that suggests the creation of new extension methods. Most of the time, you’ll be using extension methods rather than creating new ones.

<<  Previous Article Continue reading and see our next or previous articles Next Article >>

About Dino Esposito

Dino Esposito is one of the world's authorities on Web technology and software architecture. Dino published an array of books, most of which are considered state-of-the-art in their respective areas. His most recent books are “Microsoft ® .NET: Architecting Applications for the Enterprise” and “...

This author has published 53 articles on DotNetSlackers. View other articles or the complete profile here.

Other articles in this category


Developing a Hello World Java Application and Deploying it in Windows Azure - Part I
This article demonstrates how to install Windows Azure Plugin for Eclipse, create a Hello World appl...
Android for .NET Developers - Building a Twitter Client
In this article, I'll discuss the features and capabilities required by an Android application to ta...
Ref and Out (The Inside Story)
Knowing the power of ref and out, a developer will certainly make full use of this feature of parame...
Developing a Hello World Java Application and Deploying it in Windows Azure - Part II
In this article we will see the steps involved in deploying the WAR created in the first part of thi...
Android for .NET Developers - Using Web Views
In this article, I'll show a native app that contains a web-based view. The great news is that HTML ...

You might also be interested in the following related blog posts


New Entity Framework Feature CTP for VS2010 Beta 2 read more
Introducing Versatile DataSources read more
I finally got my Behringer Podcastudio working read more
Avoid Entrenched Dependencies read more
Create a SQL Azure CRUD Application with Telerik OpenAccess and the WCF Wizard read more
Part 3: Accessing Security and Authentication in Silverlight using .NET RIA Services. read more
Next version of EF Code Only Design laid out by MS read more
WPF Localization Guidance Paper Posted on CodePlex read more
Visual Studio: Why is there no 64 bit version? (yet) read more
Visual Studio 2010 1-Click Publishing read more
Top
 
 
 

Discussion


Subject Author Date
placeholder Extension methods Oleg Zhukov 10/4/2008 1:13 AM

Please login to rate or to leave a comment.

Free Agile Project Management Tool from Telerik
TeamPulse Community Edition helps your team effectively capture requirements, manage project plans, assign and track work, and most importantly, be continually connected with each other.