Extension Methods

In my series on the new C# features, I had previously blogged about –

In this post, I will be talking about Extension methods. Extension methods allow new methods to be added to an existing class without having to actually extend the class using inheritance.

For instance, if you wanted to add a function called ReverseString to the String class, you can add it without creating a new class that inherits from String. Of course, String being a sealed class cannot be extended and adding a function to it is not possible via inheritance.

The syntax for doing this looks like this –

public static string ReverseString(this string str)
{
   //code to reverse the string
}

Notice that the function has to be static and it takes this followed by the type to which the extension method needs to be added to as the first parameter.

Intellisense

Once an extension method has been created, it shows up in Intellisense – which is quite handy.

image

Notice that the icon for an extension method is different to the usual ones.

Usage Rules

When using extension methods, there are few rules that need to be followed –

  • Extension methods have to be declared in a static function in a top level static class
  • The first parameter has to start with “this” and it cannot appear multiple times in the parameters
  • The keyword “this” must be followed by the type that needs to be extended. The type can be an interface, abstract class, a concrete class or even a sealed class.
  • You cannot use things like “ref” and “out” with “this”
  • You cannot extend Properties, Events or operators (something for the future version, perhaps 🙂 ?)

Ambiguity

If you have the same extension method declared in two separate static classes, then the compiler will throw an error message saying that the call is ambiguous when the actual function is called in code. Unlike namespaces that help resolve classes that share the same name, there is no way to resolve function name clashes.

Extension methods that currently exist

.NET framework 3.5 comes loaded with a lot of extension methods. For instance, the IEnumerable interface has extension methods such as Aggregate, Average, Concat, Count, GroupBy, etc. A lot of these extension methods are essential for implementing LINQ (which will be covered in a future post).

More Examples

Extension methods can have additional parameters, as this example shows –

public static string ExtensionMethodWithParameter(
                      this string str, 
                      string value)
{
    //Do nothing, it is just an example
    return str;
}

You can also add extension methods to arrays –

public static float MyAverage(this int[] intArray)
{
    float sum = 0;
    foreach (var element in intArray)
    {
        sum += element;
    }
    return sum / intArray.Length;
}

They can also be added to the base class of them all – “object”. For example, this function converts any object into an Xml representation, based on its properties –

//Simple, shallow implementation. Converts any object to Xml
public static string ToXml(this object o)
{
    Type myType = o.GetType();

    XmlDocument xmlDoc = new XmlDocument();
    XmlDeclaration xmlDeclaration = xmlDoc.CreateXmlDeclaration(
        "1.0", "utf-8", null);

    // Create the root element
    XmlElement rootNode = xmlDoc.CreateElement(
        XmlConvert.EncodeName(myType.Name));
    xmlDoc.InsertBefore(xmlDeclaration, 
        xmlDoc.DocumentElement);
    xmlDoc.AppendChild(rootNode);


    var properties = myType.GetProperties();
    foreach (PropertyInfo prop in properties)
    {

        XmlElement childNode = 
            xmlDoc.CreateElement(prop.Name);
        childNode.AppendChild(
            xmlDoc.CreateTextNode(
            prop.GetValue(o, null).ToString()));

        rootNode.AppendChild(childNode);
    }


    return xmlDoc.InnerXml;

}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s