Sunday, January 20, 2008

Demystifying C# 3.0 - Part 3: Extension Methods


Demystifying C# 3.0 - Part 3: Extension Methods
Posted on 6/30/2006 @ 8:41 PM in #Vanilla .NET 2 comments 4014 views
If you've been following my blog, you would have noticed that I've been trying to talk about new C# 3.0 features one by one. I am trying to take the technical jargon out, and bring these features down to an understandable level.
You may want to read the two features I have already talked about below -
a) Demystifying C# 3.0 - Part 1: Implicitly Typed Local Variables "var"b) Demystifying C# 3.0 - Part 2: Anonymous Types
So here goes, Part 3: Extension methods.
Frequently you are handed a class, such as System.String, or System.Int32, that you "wished" had that one extra method that would make your life so much easier - but damn it doesn't have that method. In certain instances you can inherit and add, but you know that is tougher than it sounds in many cases (abstract/virtual), and in certain cases impossible (sealed).
Extension methods, solve that problem. You can now add newer methods, specific to your business domain - to existing types, that you did or didn't write.
So if you wanted an extra method called "SpankMonkey", you could now write code like below
int i = 10 ;i.SpankMonkey() ; // Spanks the monkey per the logic you wrote.
How neat !!! But don't go around misusing this *feature*, because Extension methods are both less discoverable and more limited in functionality than plain vanilla instance methods such as ToString(). Use them only if you must.
So how do you write an extension method?
Well thats easy, you simply put the "this" keyword as the first parameter of the extension method ~ which is a static method in a class. So you could write code as below
public static class myExtensions{ public static void SpankMonkey(this int i) { Console.WriteLine("SPANK!!"); }}
Sure you could have complicated implementations such as -
public static int DoubleMe(this int i){ return i + i ;}
You could call the above using -
int i = 10;Console.WriteLine(i.DoubleMe()) ; // Prints 20
You could also pass in a "generic" instead of an "int" or "string" etc.
Extension Method Resolution:
An obvious question here is, what if your class implements a method, AND there is an extension method that looks, talks, walks the same way - that is of the same name? Which gets called?
The answer is - "Whichever is the closest". In other words,
Strongly Typed instance methods _will_overrule_ Strongly Typed extension methods _will_overrule_Not Strongly Typed instance methods _will_overrule_Not Strongly Typed extension methods.
Whoaa that's confusing. :)
This code makes it easy to eat the above 4 lines.
public static class E{ public static void F(this object obj, int i) { } public static void F(this object obj, string s) { }}
public class A { }

public class B
public void F(int i) { }
public class C
public void F(object obj) { }
public class X
public static void Test(A a, B b, C c)
a.F(1); // E.F(object, int) is called
a.F("hello"); // E.F(object, string) is called
b.F(1); // B.F(int) is called
b.F("hello"); // E.F(object, string) is called
c.F(1); // C.F(object) is called
c.F("hello"); // C.F(object) is called
Of course if nothing matches, you get a compile time error (duh!)Neat !! So now we know what "Extension methods" are, how you can write them, how you can use them, and how they may be called.Next we'll be talking about Lambda Expressions. See ya around !! :-)

Labels: , , ,


Post a Comment

Subscribe to Post Comments [Atom]

<< Home