Click here to monitor SSC

Damon Armstrong

Caffeine Induced Tirades about .NET and Life
And don't forget to check out my latest Simple-Talk articles
View Damon Armstrong's profile on LinkedIn      Add to Technorati Favorites      Add to Google     

Thoughts on C# Extension Methods

Published Friday, April 23, 2010 5:06 PM

I'm not a huge fan of extension methods.  When they first came out, I remember seeing a method on an object that was fairly useful, but when I went to use it another piece of code that method wasn't available.  Turns out it was an extension method and I hadn't included the appropriate assembly and imports statement in my code to use it.  I remember being a bit confused at first about how the heck that could happen (hey, extension methods were new, cut me some slack) and it took a bit of time to track down exactly what it was that I needed to include to get that method back.  I just imagined a new developer trying to figure out why a method was missing and fruitlessly searching on MSDN for a method that didn't exist and it just didn't sit well with me.

I am of the opinion that if you have an object, then you shouldn't have to include additional assemblies to get additional instance level methods out of that object.  That opinion applies to namespaces as well - I do not like it when the contents of a namespace are split out into multiple assemblies.  I prefer to have static utility classes instead of extension methods to keep things nicely packaged into a cohesive unit.  It also makes it abundantly clear where utility methods are used in code.  I will concede, however, that it can make code a bit more verbose and lengthy.  There is always a trade-off.

Some people harp on extension methods because it breaks the tenants of object oriented development and allows you to add methods to sealed classes.  Whatever.  Extension methods are just utility methods that you can tack onto an object after the fact.  Extension methods do not give you any more access to an object than the developer of that object allows, so I say that those who cry OO foul on extension methods really don't have much of an argument on which to stand.  In fact, I have to concede that my dislike of them is really more about style than anything of great substance.

One interesting thing that I found regarding extension methods is that you can call them on null objects. Take a look at this extension method:

namespace ExtensionMethods
{
 
public static class StringUtility
  {
   
public static int WordCount(this string str)
   
{
     
if(str == null) return 0;
     
return str.Split(new char[] { ' ', '.', '?' },
        StringSplitOptions.RemoveEmptyEntries
).Length;
   
}
  }  
}

Notice that the extension method checks to see if the incoming string parameter is null.  I was worried that the runtime would perform a check on the object instance to make sure it was not null before calling an extension method, but that is apparently not the case.  So, if you call the following code it runs just fine.

string s = null;
int words = s.WordCount();

I am a big fan of things working, but this seems to go against everything I've come to know about instance level methods.  However, an extension method is really a static method masquerading as an instance-level method, so I suppose it would be far more frustrating if it failed since there is really no reason it shouldn't succeed.

Although I'm not a fan of extension methods, I will say that if you ever find yourself at an impasse with a die-hard fan of either the utility class or extension method approach, then there is a common ground.  Extension methods are defined in static classes, and you call them from those static classes as well as directly from the objects they extend.  So if you build your utility classes using extension methods, then you can have it your way and they can have it theirs. 

by Damon

Comments

 

Jason Haley said:

Interesting Finds: April 24, 2010
April 24, 2010 5:43 PM
 

optiks said:

Compare:

var x = ...
             .Where(x => x.Salary > 1000)
             .Take(10)
             .Select(x => x.Salary)
vs.

var x = Select(Take(Where(..., x => x.Salary > 10), x => x.Salary).

Which do you think is more readable? I think the first is by far.

I also *like* the fact that you can use extension methods on null references, it allows you the *ability* to do things if the reference is null if you so wish. For example, you could do something like possibleNullReference.ThrowIfNull or possibleStringNullReference.IsNullOrEmpty().

Personally I think the "new developer may struggle" argument is valid, but shouldn't stop us moving languages forward if they offer significant benefits. And I believe extension methods do. Bring on extension properties!
April 25, 2010 12:10 AM
 

optiks said:

Oops, I meant:

var x = Select(Take(Where(..., x => x.Salary > 1000), 10), x => x.Salary).

Fluent interfaces don't offer the same ease of use. Builders can pollute a clean API.
April 25, 2010 12:13 AM
 

Damon said:

@optiks: I am also of the opinion that you should NOT avoid good technology because it may confuse new developers.  Otherwise you'll just hurt new developers by limiting their exposure to what could be really beneficial practices.

The ability to work on null objects is definitely interesting.  I was talking with Jeff Burt today and he mentioned a ToStringSafe() method that basically avoids you have to worry about null references when displaying data.  Having encountered that issue a number of times when binding to data, I see that as a very useful and compelling option.  

Perhaps I should revise my statement to say that I don't like extension methods for ad-hoc utility methods.  When you have something like LINQ and there are a series of extension methods that work together in a framework, it's quite nice.
April 30, 2010 9:40 PM
 

Weekly Link Post 143 « Rhonda Tipton's WebLog said:

May 3, 2010 5:09 PM
You need to sign in to comment on this blog
Latest articles
Checking Out SQL Backup Pro 7’s New Automatic Backup Verification
 Wouldn't it be great to offload the daily chore of checking the integrity of your production... Read more...

Chuck Lathrope: DBA of the Day
 Chuck Lathrope was a finalist for the Exceptional DBA of the Year award in 2009. We contacted him to... Read more...

Backups, What Are They Good For?
 Pixar recently confessed, in an engaging video, that Toy Story 2 was almost lost due to a bad backup,... Read more...

C# Async: What is it, and how does it work?
 The biggest new feature in C#5 is Async, and its associated Await (contextual) keyword. Anybody who is... Read more...

SQL Server 2012 AlwaysOn
 SQL Server AlwaysOn provides a high-availability and Disaster-recovery solution for SQL Server 2012. It... Read more...