Saturday, April 19, 2008

C# Extension Methods Part 1: Introduction

Extension methods are a new feature of C# 3.0 with .Net 3.5. They allow you to extend existing classes with new methods without having to create a whole new class that inherits from the class you want to add the method to. First off, why would you want to do this?

Well, as an example LINQ makes heavy use of extension methods to provide the functionality to create new expressions easily. A LINQ extension method might extend IQueryable to apply a custom where clause, for example. In fact, as part of the Visual Studio 2008 samples you'll find a set of extension methods that does just that.

So what does an extension method look like? Here's a very simple example:

public static string Reverse(this string str)
{
if (str == null)
{
throw new ArgumentNullException("str");
}

StringBuilder builder = new StringBuilder();
for (int i = str.Length - 1; i >= 0; i--)
{
builder.Append(str[i]);
}

return builder.ToString();

}

Here we have a static class StringExtensionMethods that contains a Reverse method, which reverses the order of the characters in a string.

Notice that the parameter being passed into the Reverse method has the "this" keyword preceding it. This tells the compiler that this is an extension method for the string class.


You can now use this method on any string object in any class that uses the namespace that this static class is in. We also get full Intellisense support in Visual Studio 2008:

reverseCodeGrab


There are a few things to be aware of though. Consider this piece of code:

string thisIsNull = null;
Console.Write(thisIsNull.Reverse());

If Reverse was a standard method on the string object, then we would get a NullReferenceException being thrown when we try to call the method.

However, an extension method on a null object will still be called. It is the responsibility of the extension method to check for null values.

The extension method is pretty much just syntactic sugar around a standard static "helper" style method. So when the method is called it doesn't actually need to be part of an instance.

For this reason, make sure you should still check that the parameter is not null before using it, as you would in a normal method.
As a quick aside, this is a perfectly functional extension method:

public static bool IsNull(this object obj)
{
return obj == null;
}

It could then be called like this:

string thisIsNull = null;
if (thisIsNull.IsNull())
{
Console.Write("Was null");
}

So we can create extension methods that easily provide some additional functionality to a class. Next time, I'll show how I've implemented a simple extension method to Log4Net.

No comments: