One of my favorite C# 3.0 features is Extension Methods. In short, it ables you to extend an existing type with additional behaviors. For example, you can consider to extend the type System.Int32 (aka “int”) with a new method named IsEven.
The syntax is quite trivial:
public static class Extentions
public static bool IsEven(this int i)
Notice the “this int” which means “I want to extend the type int“.
Now I can write the following code (fully IntelliSense-d and compile time checking):
using Lnbogen.Extensions; //<- this will load the extensions, it won’t compile without it!
… void TestIsEven()
int num = 5;
What’s going on behind the scenes is quite simple, the compiler got a little “smarter” and now knows to look for Extension Methods in the imported namespaces. I don’t want to elaborate too much about the syntax and requirements as Anders Hejlsberg makes it all clear in his MSDN video: C# 3.0: Future Directions in Language Innovation.
Let me direct you to the real meat:
Extension Methods is going to change the way we enhance “already used” code. Up to now, looking at that need (for backward compatibility), Microsoft suggested to create an interface and an abstract class that implement this interface. This allows us to extend the abstract class simply by providing new virtual members without breaking the code. The problem in this solution is that things were getting out of sync really fast leaving our interfaces shy & dry(=out of date), just to avoid breaking changes. Even worse, due to the fact that multi-inheritance is forbidden, inheriting from the abstract class pretty much slammed the door on most of our design choices.
Let’s face it; Interfaces were programmer’s nightmare(before you hack my blog and delete this post, bare with me). On one hand, we’re reluctant to implement an interface with 10 members as we prefer to finish our tasks in this century but on the other hand, we want our interface to expose as much API as it can to allow easy usage for its customers(=programmers) and to avoid casting it(the interface) to “specialist” interfaces.
Well, Extension Methods allows us to extend any type. Do you get my drift here?
You can now enhance any interface you’ve ever exposed thus making old interfaces incredibly strong. You can define a lightweight interface(easy for the implementor of the interface) and extend its abilities without breaking any existing code(enrich the customers of the interface). This is exactly what Microsoft did with LINQ. They have extended IEnumerable<T> with many Query methods such as “Select”, “From”, “Where”, “GroupBy”, “Join” (and much more…) to enhance it with a great set of new methods while still keeping the original interface untouched. All we have to do is simply import System.Query namespace.