Ziff Davis EnterpriseDevLife
Advertisement
Advertisement

Wednesday, December 26, 2007 9:11 AM/EST

Extension Methods are growing on me

Yes of course LINQ is really the golden apple of VS2008, but extension methods are really growing on me.

Not only are they clever and convenient, but they also provide some magic when combined with anonymous types. I am trying to get Extension Methods closer to the front of my brain, so that I will think of using them more frequently as there are so many cases where they solve a problem more fully then more common solutions.

Extension Methods are one of the new language enhancements for VB9 and C#3.0. They allow developers to extend existing types and classes with new methods.

If you are not familiar yet with Extension Methods here is the MSDN documentation for VB and the documentation for C#. These are written differently in the two languages, so be sure to take a look at both in order to see the full picture.

In my opinion, the three biggest problems these solve are:

1) Add functionality to existing (even sealed) classes or types:

Take System.String. A typical function to write for Strings is a print function that might look like :
VB: MyFuncs.Print(byval str as String)
or C#: MyFuncs.Print(String str)

This requires knowing that MyFuncs.Print exists.

Instead, you could write a method extension called Print that applies to System.String:

VB:
(note, this blog has a hard time with code in angle brackets...so I have put spaces around them)
< Extension() > _
Public Sub Print(ByVal aString As String)
Console.WriteLine(aString)
End Sub

C:
public static int Print(this String str)
{
Console.WriteLine(str);
}

Now, anytime I have a string, the Print method is available and discoverable through intellisense.

2) Extension methods combined with generics are really amazing because they allow you to add methods even to anonymous types.

How would you add functionality to an anonymous type? It's a bit of an oxymoron, isn't it? However, with extension methods you can. I loved this example by Jarsolow Kowalksi from the Entity Framework team in the forums which allows me to use the ToTraceString method (which exists for ObjectQuery) on iQueryables, even iQueryables of anonymous types!


static string ToTraceString(this IQueryable t)
{
// try to cast to ObjectQuery
ObjectQuery oqt = t as ObjectQuery;
if (oqt != null)
return oqt.ToTraceString();
return "";
}

This even takes care of anonymous types, so you can write:
using (NorthwindEFEntities context = new NorthwindEFEntities())
{
// connection must be open in order for ToTraceString() to work
context.Connection.Open();
var p = from c in context.Customers
where c.City == "London"
select new { Name = c.CompanyName, City = c.City };
Console.WriteLine(p.ToTraceString());
}


3) Add functionality to many classes at once

Lastly, if you can keep Extension Methods in the front of your mind, you might recognize many places where you can use them. In another forum thread, I had suggested a solution to someone which added a property to an entity class using a partial classes. The problem we were solving is that in an Entity Data Model, when a PK/FK relationship exists between entities, the foreign key is replaced by a navigation property and getting back to that foreign key requires some convoluded code. Yaakov Davis, who had asked the original question, quickly realized that the property I was suggesting would be useful for all entities that contain foreign keys, not just the one he was asking about. So rather than make a property for that one class, he wrote an extension method for all Entities (any class that implements the Entity class)to return the value of the foreign key. You can see his solution here.

TrackBack

TrackBack

http://blogs.devsource.com/cgi-bin/mte/mt-tb.cgi/12310

Comments (1)

Another nice usage of extensions methods is to create a fluent interface, making sure that your extensions methods always return an object where you can act on.

ex:

"my life".Split(' ').PrintEach();

This example is not very useful but you get the idea. You can look at libraries like prototype (js) or languages like Ruby to get some inspiration.

Post a Comment

 
 

Advertisement

Syndication

Subscribe: