Developer

Code concepts: C#'s extension methods

C#'s extension methods are a way of adding additional functionality to an existing class without subclassing it or having access to the source code. Justin James thinks programmers should definitely add extension methods to their toolkit.

 

When I first became really acquainted with object-oriented programming, one of my first goals was to subclass the string class and add the features I thought that it was missing. It quickly became apparent to me that subclassing standard classes in order to add additional functionality does not pay in many circumstances, because you need to keep recasting the object every time you want to use it outside of your code. C# has a better solution to this scenario in the form of extension methods. (For better or for worse, the project in this scenario kind of faded away.)

Extensions methods are a way of adding additional functionality to an existing class without subclassing it or having access to the source code. With a simple syntax, it is suddenly trivial to add all of the additional functionality you need, without disrupting existing code or requiring a lot of casting calls. Once an extension method is created and within scope, the method is available to any instance of the class to which the method is added. In many ways, extension methods bring some of the flexibility that languages such as Ruby and Python give their developers, while still working within the C# language.

The rules of extension methods are easy to understand. Extension methods are placed within a static class and should be declared as static. From there, extension methods look like any ordinary method except for one minor change: The first parameter should be in this form: this TypeToExtend parametername. This indicates to the compiler that you are creating an extension method to the class TypeToExtend. It also declares that within the method body, there is a variable called parametername that represents the value of the instance.

Let's look at an example. We add a Matches method to the string class, which accepts a pattern for a regular expression and regular expression options. The method creates a Regex object using the pattern and options and returns the Matches object from the Regex when run against the string. We will also create an overload of this new method that does not require any options to be passed in and just uses the Regex default options. Here's the code:

namespace SampleProject

{

    public static class StringExtensions

    {

        public static MatchCollection Matches(this string source, string Pattern, RegexOptions Options)
        {

            Regex re = new Regex(Pattern, Options);

            return re.Matches(source);

        }

        public static MatchCollection Matches(this string source, string Pattern)

        {

            Regex re = new Regex(Pattern);

            return re.Matches(source);

        }

    }

}

In this code, the parameter source is used as a variable within the method. But, when you actually call the method, source is not a parameter that gets passed to the method at all by the calling code. Here is an example of calling this extension method:

string value = "Hello World!";

if (value.Matches("Hello").Count > 0)

{

    Console.WriteLine("Yes, it says \"Hello\"!");

}

As you can see, we do not actually pass the source parameter to the method. In addition, you can see how the extension method has seamlessly become a member of the string class without the need to subclass string. It's important to note that, if you want to use the extension method, the class that contains it must be available to the calling code and within scope. Alternatively, you may call the extension method as a static method of its enclosing class. In this case:

string value = "Hello World!";

if (StringExtensions.Matches(value, "Hello").Count > 0)

{

    Console.WriteLine("Yes, it says \"Hello\"!");

}

For more in depth details on extensions methods, see the C# 3.0 language specification (Word format).

Extension methods are far from a complete replacement for class inheritance; there will always be a need for specialized versions of classes. But extensions methods really shine for adding limited functionality without having to work with the issues that come with subclassing.

You should definitely add extension methods to your toolkit. I think that after one or two uses, you will see the power of this technique.

J.Ja

Disclosure of Justin's industry affiliations: Justin James has a working arrangement with Microsoft to write an article for MSDN Magazine. He also has a contract with Spiceworks to write product buying guides.

———————————————————————————————————————————-

Get weekly development tips in your inbox Keep your developer skills sharp by signing up for TechRepublic's free Web Developer newsletter, delivered each Tuesday. Automatically subscribe today!

About Justin James

Justin James is the Lead Architect for Conigent.

Editor's Picks

Free Newsletters, In your Inbox