Extension Methods

It is quite common for programmers to write a method/function in their application which is applied to a basic object. Good OOP style might dictate that we would build the method into the class. For example, we might have a string which is holding a UK postcode, we would write function to check if it is valid. The first attempt to OOPify (sorry!) this might look like this:

public class UKPostCode {
  public string PostCode { get; set; }
  public bool isValid() {
    bool result = // some code to check actual postcode??
    return result; 
  }
}
...
UKPostCode postcode = new UKPostCode { PostCode = TextBox1.Text };
if (postCode.isValid())
  { doSomething(); }
else
  { reportError(); }

This works, but it requires us to take our basic string property and package it up into an object. Wouldn't it be great if we could extend the definition of the string class to include a method such as isValidPostCode? Extension methods do just this. If we create such an extension method for the string object we can use code such as follows:

if (TextBox1.Text.isValidPostCode())
  { doSomething(); }
else
  { reportError(); }

This is a much cleaner solution to the problem. So what does an extension method look like? Unfortunately, it is a rather obscure piece of syntax, but the power it yields is worth the effort in getting to understand it. An extension method is a static method of a static class and the method has to indicate the object type which it is extending. In the case of our postcode problem, we would need a class as follows:

public static class MyStringExtender
{
  public static bool isValidPostCode(this string postcode)
  {
    Regex pcodevalidator =
      new Regex(@"^([A-PR-UW ... 2}|GIR 0AA)$"); // trimmed
    return pcodevalidator.IsMatch(postcode);
  }
}

The only thing which distinguishes this class as an extension method, rather than a utility class with some helper methods is the use of the keyword 'this' before the first parameter. This tells the compiler that it can use the method with an object of the same type as the parameter. We must of course put a 'using' statement in our code to allow the compiler to find the class and its extension method(s) when we use it. Once this is done the intellisense/code completion feature in Visual Studio will include our new method in the list of methods while we are typing our code.

Our extension methods can include extra parameters which would allow us to write more complex extensions, for example:

Location loc = myGPS.GetLocation();
if (TextBox1.Text.isCloseTo(loc)
  { Label1.Text = "Getting close"; }
else
  { Label1.Text = "Not quite there yet!"; }

The extension method would look like this:

public static class MyStringExtender
{
  public static bool isCloseTo(this string postcode, Location loc)
  {
    double distance = // write code to work out distance between
                      // current postcode and the GPS location
    return distance < 100; // metres
  }
}

You can even use extension methods on literal values too, for example:

  bool nearlyAtWork = "CH1 4BJ".isCloseTo(myloc);

The power of extension method is demonstrated by the build in libraries for querying in the System.Linq namespace. The methods in this library provide built in methods allowing you to query a range of data structure, most importantly structures which implement the IEnumerable interface, such as Lists and Array types.

Built in LINQ extension methods

If you include "using System.Linq;" in your code file you can make use of built in extension methods for a range of data structures. These extension methods are particularly important for the developer as they allow you to use a consistent syntax for accessing and organising resulting data across a range of data types, e.g. SQL, XML, arrays etc.

Take for example our list of Books. We can use the LINQ extension methods to perform a range of manipulations on the data. There are methods such as:

Average
To return the average value of some data field in a collection of objects
Max (or Min)
To return the maximum (minimum) value of some data field in a collection of objects
Where
To return a subset of a collection of objects, based on some criteria

Distinct extension libraries are available which target different kinds of data, for example Linq to SQL and Linq to XML. Each library includes domain specific extensions, e.g. the Descendants method returns a list of XML elements which are the immediate descendant of a given XML node element.

To make use of these extension methods you need to be familiar with another new feature in C# - Lambda expressions - although it is possible to manage without them, except it require more coding and more complex syntax.

Valid XHTML 1.0! | Valid CSS! | WCAG Approved AA
Page design by: John P Scott - Hosting with: Netcetera