Thoughts on C# Extension Methods
- by Damon
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.