C# Extension Methods: Syntactic Sugar or Useful Tool?
Last week a colleague introduced me to extension methods (C#, VB) in .Net. If you're not familiar with extension methods, they were added in Visual Studio 2008 to provide a means for adding functionality to existing types without creating a new derived type. Extension methods are called as if they were instance methods of the existing type. For example, if I wanted to know how many vowels there were in a string, I could add a
Now the function is displayed by Intellisense as if it was a member function,
and I can then call it like this:
(By the way, I’m not advocating appending
My initial reaction was ‘Sweet!'. However, after thinking about it for a couple of days (no, my brain doesn’t work very fast), I began to wonder if there was anything more to this than hiding the
Other than the method showing up in Intellisense for the type, extension methods hadn't added anything. I was sure there must be something more. Maybe the compiler was doing something under the hood? So I compiled the following code and opened the resulting executable in ILDasm. (The non-extension method has been renamed to
Here's the resulting IL:
So there really isn't any functional difference between extension methods and normal static methods.
If, then, extension methods are essentially syntactic sugar, should they be used? This comes back to one of the basic principles of clear communication: consistency. If you are going to use extension methods, use them everywhere; if you are going to use normal static methods, do that everywhere. But please, please, please don't mix the two. One of my pet peeves when trying to understand a new code base is inconsistency because it means that I constantly have to either look elsewhere in the code or in the documentation (if any) to discover how to use it. Mixing extension methods and static methods is certain to cause confusion.
The biggest advantage to extension methods is discoverability: when I type my variable name in an Intellisense-aware editor, the extension methods are added to the list. In contrast, when using a normal static method, I have to remember the name of the class that implements it in order to call it. Another plus is the ability to 'extend' sealed classes and valuetypes. I often find that BCL valuetypes don't have the conversions that I need. Now, I can add the conversion and have it display in Intellisense. A third is that they integrate seamlessly with generics. This is not an essential, but it sure comes in handy sometimes. Finally, my code will no longer be littered with calls to
There are also a couple of things I don't like. Adding the
Hmmm...there's nothing wrong with the static method because I fixed the syntax error. Why won't this #$!$!#$#$ file compile? A second issue I have with extension methods is that they can pollute Intellisense--thus frustrating their biggest advantage. Since extension methods are inherited by all derived classes, deeply derived classes can end up with so many methods that it's difficult to find the one you're looking for. However, my biggest beef is that the differences between static and instance methods are no longer obvious in the calling function. Consider the following code:
What happens when
So my answer is yes to both questions: extension methods are syntactic sugar but they can be useful syntactic sugar. For myself, I'm going to begin using extension methods because I like the discoverability and understand the potential pitfalls. However, I'm going to give myself this advice:
If I've missed any pros or cons, please post a comment-discussion is good for the soul.
DISCLAIMER: The information in this weblog is provided "AS IS" with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of my employer.