Extension Methods in C#3.0
       by kirupa  |  1 June 2009

When creating an application, you declare variables and use objects that all have a Type associated with them. Types you probably use commonly include int, double, string, Array, etc. One common type that I like to use often is a List. As with any object you use in .NET, you have access to all methods and properties the object exposes.

For example, any object you declare of type List comes with a sizable amount of methods and properties that allow you to do things on the List or the data stored inside them:

These methods and properties live either on the List itself, or they live on the various classes that make up your List. Think of this is an exclusive club that members or only members' friends can gain access to.

What if you had an existing application that used the List type a lot and you wanted to add the ability to, let's say, remove duplicate values from your list. What are your options for solving this dilemma?

You have several options. One option is to create your own type that extends List, and in this type, have your custom method that removes duplicate values. Another option is to simply create a separate static method that takes a List as its argument and returns a filtered version of the same List with all duplicate values removed.

Both of these options have their advantages and disadvantages, but you now have another way of solving this problem. You can use what are known as extension methods and have your custom method that removes duplicates appear as a member of the List type itself:

The exclusive club is still very exclusive, but you were now able to sneak in by following a regular member indoor. The RemoveDuplicates method is kind of like that person who snuck in. It is not a method your List type (or types that List derives from) provide, but notice that I am able to use it almost as if it were. In this article, I will describe the magic that is an extension method and possibly teach you how to sneak into exclusive, cool establishments.

An Example
To see an extension method in action, download my example from the following link and extract the contents of the Zip file into some location:

Download Final Source

Once you have downloaded and extracted these files, open the ExtensionMethodsSample.sln in Visual Studio. This isn't a particularly visual sample where hitting F5 will show you something useful. Instead, everything relevant is in code with no UI backing it, so open Window1.xaml.cs instead.

Look at the code in your MainWindow class where the example lives:

public partial class MainWindow : Window
{
public MainWindow()
{
// Required to initialize variables
InitializeComponent();
 
List<string> input = new List<string>();
input.Add("There");
input.Add("Here");
input.Add("Sneer");
input.Add("There");
input.Add("Near");
input.Add("Meer");
input.Add("Here");
 
List<string> result = input.RemoveDuplicates();
}
}

What I am doing is declaring a new List object named input and adding some text to it. Notice that the text I am adding is not unique. The words There and Here are being duplicated. What I want to do is remove those duplicated values. In the past, if I wanted these duplicate values removed, I would do something as described in this tutorial.

In the world of extension methods, though, all I needed to do is as follows where I call a RemoveDuplicates method on my input List object itself:

List<string> result = input.RemoveDuplicates();

This is possible thanks to extension methods, and while creating your own extension method is not quite as easy as using one, it is actually not particularly difficult either. Let's look at how to create this RemoveDuplicates extension method that works on your List.

Creating the Extension Method
Creating an extension method is not very hard, and the tricky part is just remembering the syntax for doing all of this. Below is the code for my RemoveDuplicates extension method:

public static class Extensions
{
public static List<T> RemoveDuplicates<T>(this List<T> input)
{
Dictionary<T, int> uniqueStore = new Dictionary<T, int>();
List<T> finalList = new List<T>();
 
foreach (T currValue in input)
{
if (!uniqueStore.ContainsKey(currValue))
{
uniqueStore.Add(currValue, 0);
finalList.Add(currValue);
}
}
return finalList;
}
}
 
public partial class MainPage : UserControl
{
public MainPage()
{
// Required to initialize variables
InitializeComponent();
 
List<string> input = new List<string>();
input.Add("There");
input.Add("Here");
input.Add("Sneer");
input.Add("There");
input.Add("Near");
input.Add("Meer");
input.Add("Here");
 
List<string> result = input.RemoveDuplicates();
}
}

Let's look at the code in greater detail by starting at the very top:

public static class Extensions

Your extension method has to live in a class that is static and non-generic. It would be nice if you could just have your extension method be included in the class that defines your MainPage your usercontrol, but unfortunately you cannot do that.


public static List<T> RemoveDuplicates<T>(this List<T> input)

In this line, you actually declare your extension method called RemoveDuplicates that returns a List when called. Notice that your extension method is public, static, and takes a reference to the class it is extending (List<T>) as an argument.


List<string> input = new List<string>();
input.Add("There");
input.Add("Here");
input.Add("Sneer");
input.Add("There");
input.Add("Near");
input.Add("Meer");
input.Add("Here");
 
List<string> result = input.RemoveDuplicates();

The above code lives in my MainPage class, and it is here that I actually call my RemoveDuplicates extension method. To reiterate what I mentioned in my introduction, notice that I am calling RemoveDuplicates almost as if it where a method that was native to the List class itself.

Conclusion
That is really all there is to using extension methods in both WPF and Silverlight. They are a great way for you to enhance an existing type with more functionality without having to extend the type or perform other clever acrobatics.


Just a final word before we wrap up. If you have a question and/or want to be part of a friendly, collaborative community of over 220k other developers like yourself, post on the forums for a quick response!

Kirupa's signature!




SUPPORTERS:

kirupa.com's fast and reliable hosting provided by Media Temple.