Extension Methods

by mgordon 9. November 2007 04:33

With the release of the next version of Visual Studio and the .Net languages, a new feature called Extension Methods will be available.  In a general sense, these allow you to add functionality to classes without having to modify their source including any class in the .Net Framework.  This is a very similar idea to what is offered in a dynamic language such as Ruby, but in the strongly typed .Net languages.

 For example, Ruby has a string type.  If, for some reason, we wanted to add a method to the string class that would return the string wrapped in html that would render the string in a particular color, we could do something like this.

class String
  def to_htmlColor (color)
    "<font color='" + color + "'>" + self + "</font>"
  end
end

puts "fido".to_htmlColor("#AAAAAA")

This would return the string <font color='#AAAAAA>fido</font>

In C#, we can accomplish a similar thing this way.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace testExtensionMethods
{

    class Program
   
{
       
static void Main(string[] args)
        {
           
Console.WriteLine("423".to_i());
           
Console.WriteLine("xxx".to_i());
        }
    }

    public static class Extensions
   
{
       
public static int to_i(this string s)
        {
           
int i;

           
if (!int.TryParse(s, out i))
            {
               
throw new InvalidCastException("String cannot be converted to an integer");
            }
           
return i;
        }
    }
}

Here, I've added a to_i() method to the .Net string class that converts the string value to an integer if it can and throws an exception if it can't.  What triggers the desired behavior is the inclusion of the this keyword in the method signature.  This syntax tells the compiler that the method is to be added to the string type since it follows the this keyword.  The new method can be used on the string class anytime my extension class is in scope.  For example, I could have added my Extensions class in a different namespace and anytime that namespace was included with a using or imports statment, my extension method is available.

Certainly, this is a more brief syntax than int.Parse("423") and feels more natural.  I can recall several situations where I've had to string together commands from various classes in a single statement.  Extension methods could help out with creating convenience methods to replace complicated syntax in these situations.

Scott Gutherie discusses how extension methods were used to add functionality to classes for use with Linq, here.  When the Linq namespaces are included, standard classes are augmented with new functionality that make them easier to use in conjunction with Linq.  In thinking about how I might use these, one idea that came to mind was in a situation where I had a data transport class.  It needs only to be able to contain the data when it's moving between layers, but when it arrives in the business layer from the data layer, it would be nice to be able to add functionality to the class.  This would keep the class nice and tight as it is passed around, but when you need to perform some action on the data contained within, extension methods could be used to add that functionality.  In a way, this technology allows you to have a class function differently based on the "mode" or context it happens to be in at any given time.  Very snazzy!

Tags: , ,

.Net | Productivity | Ruby

Comments are closed

About the author

Mitch Gordon lives and works in the great state of Georgia.

RecentPosts

Month List