Sun, Sep 18 2005 8:54 PM
Olaf Conijn
There’s more to C# 3.0 than LINQ; Extension methods
While I was watching a very cool LINQ (Language Integrated Query) demo by Anders Hejlsberg on Channel9, I noticed he typed something similar to the following:
using System.Query;
IEnumerable<Customer> Customers = GetCustomers();
var q = Customers.Where(c => c.City = "Londen")
.Select(c => c.CompanyName);
After doing this he briefly explained that the “Where” and “Select” methods where so called “extension methods” and new to c# 3.0, then switched over to LINQ.
> Wait, think, rewind
Extension methods? So, if I import the System.Query namespace a IEnumerable<T> suddenly gains methods such as Select and Where? That’s pretty similar to what others call Mixins and is used in Aspect Oriented Programming. This is also the technology that LINQ relies on (or is a template for).
The goal within AOP is to simplify complex application development by allowing a developer (analist or architect) to isolate requirements and their implementations.
The implementation of this (rather technical) requirement: “IEnumerable<T> should support Select and Where methods” is all done in an isolated assembly and namespace. There is no need to add such methods to IEnumerable<T>’s definition and have ‘System.Query’ logic all around the place (or at least in System.Collections.Generic as well).
Basically this could mean the end of utility classes like “System.Math” (it won’t, because that would break a lot of code, but still….).
Developing an extension method is as simple as writing method signature. Simply add a first parameter proceeded by the keyword ‘this’. The type of this first parameter will be the type you are extending.
2 examples:
public static class SerializationExtensions
{
public static byte[] Serialize(this object instance){…}
}
public static class MathExtensions
{
public static double Floor(this double x, double y){…}
}
The first example exends any class (because it extends object) with a method “Serialize()”. This logic could all be written in System.Runtime.Serialization.Binary or the Soap namespace equivalent.
The second example extends the type double with a method “Floor(double y)”, taking the double this method is called on as the first argument.
When looking at the IL this generates, the calls to extension methods show up as static calls to the static methods passing the extended object as the first argument. This makes writing extensions faster than any AOP equivalent I’ve ever seen.
A preview compiler can be found here (C# LINQ Tech Preview) and contains the C# 3.0 language specs.
Have fun