Extension methods illustrated

Extension methods are a great new feature in the .NET Framework 3.5 that let you write new methods that appear to be part of existing classes without the need to subclass or modify them.

We can explain this in simple terms with an example. Here is a useful routine that takes a string and returns what it finds between two other strings that works just fine with .NET 2.0 and .NET 1.1.

public static string Between(string value, string start, string end) {
  int startIndex = value.IndexOf(start, StringComparison.CurrentCultureIgnoreCase);
  if (startIndex == -1)
    return "";
  startIndex += start.Length;

  int endIndex = value.IndexOf(end, startIndex, StringComparison.CurrentCultureIgnoreCase);
  if (endIndex == -1)
    return "";

  return value.Substring(startIndex, endIndex-startIndex);

If this method belonged to a static StringUtilities class then you could use it like this:

string newString = StringUtilities.Between(inputString, startingString, endingString);

The problem is knowing that the StringUtilities class within the project you are working on and until you know that IntelliSense can’t even kick in. What would be nice is to add this to the String class but of course we can’t because String is sealed and besides methods everywhere create String classes and not instances of your subclass.

What would be really cool is if Visual Studio and .NET could just realize that this method is static and takes a string parameter as it’s first parameter and let it just appear as another method on the String class and just call StringUtilities behind the scenes.

That is exactly what the extension methods in .NET 3.5 achieve.

All we need to do is put this in front of the first parameter which will let VS and the compiler know that this method should appear as if it is a method against the type of that first parameter. The method must be static and visible to the code and curiously the class itself must also be static. Our signature now appears as:

public static string Between(string <em>this</em> value, string start, string end)

To call the method we simply press . after our string and IntelliSense displays all the usual methods and properties of the String class and any extension methods it can find in your project too which now includes our Between method giving us:

string newString = inputString.Between(startingString, endingString);

Nice but bear in mind the extension method can only access the public parts of the class it will appear with – there is no privileged access to protected properties or methods that would be available with sub-classing!


6 responses

  1. Avatar for steve

    Ugh, that's an ugly hack if ever I saw one, akin to how OO used to be emulated with procedural languages.

    As they add more and more 'magic' features to .Net that bypass core limitations they've built in, I wonder how hard it's going to be to pick apart a full-scale project after a couple of years development? I know it 'looks nice' but to be honest being able to tack on extra methods to core classes willy-nilly without easily being able to tell what's the standard API and what's not horrifies me.

    steve October 20, 2007
  2. Avatar for Damien Guard

    It doesn't let you tack on extra methods - it's just syntatic sugar for the compiler that calls the static method for you in a more human-readable way.

    Damien Guard October 25, 2007
  3. Avatar for steve

    I know. But as far as reading the code that's been written is concerned, it looks like a method of the class, but it isn't. Personally that would drive me nuts if I was reading someone elses code. Where the hell did that method come from? I can only imagine the crap that people will tack on to the standard String classes, and they'll all do it differently no doubt.

    Personally I think this syntactic sugar stuff can be taken way too far. Sure it's clever little tricks that a low-level developer will love playing about with, but I seriously question whether it actually adds to the overall quality of the software, and perhaps the reverse. There's a lot to be said for elegance in simplicity and directness, not layering tricks upon tricks.

    steve October 25, 2007
  4. Avatar for Kezzer

    This is actually something I had a discussion on in a Java group somewhere on the Internet. Java 7 is in development and there's been some discussions for "features" such as this. I had made a point that it's good to keep one concept straight and concise. It's like arbitrarily introducing a new word into the English language. People will say the word, no-one will know what it means, and they've never had to know, suddenly they have to learn something new even though the old approach worked just fine.

    There's a lot of short-hand stuff in C#.NET from what I remember though. I do remember partial classes mainly when I was working at Symantec, they caused me some headaches ;)

    I say stick to the traditional way, that way no-one will have to get confused :)

    Kezzer October 27, 2007
  5. Avatar for Greg M
    Where the hell did that method come from?

    How do you usually locate functions that aren't methods of a class? This is no different.

    Of course the only reason for the o.f(x) syntax instead of f(o,x) is that it indicates that o is defined in-place in the definition of o's type, so once you break that, the need for that sugar becomes questionable. But I'm pretty sure this feature isn't just sugar - can't you use it to make old classes implement new interfaces? That fixes a whole bunch of the problems you get when you try to write modular, polymorphic code in an OO language.

    Greg M November 12, 2007
  6. Avatar for Damien Guard

    Yeah it's easy to find out where it came from with "Go To Definition".

    It really is just sugar, the .NET 2.0 runtime is unchanged for .NET 3.5 - it's just new frameworks and compiler magic.

    You can't use it to make existing classes implement new interfaces, that would require runtime changes I'm sure.

    Damien Guard November 12, 2007