While I was attending the Day of .NET conference in Ann Arbor, MI last Saturday (10/20/2007) I had the opportunity to talk to an old co-worker of mine. He said something that really caught me off guard. While talking about new things that had us excited, he told me he was really excited about extensions methods and said they were really going to help him where he works. If you are new to extensions methods take a look at an old blog post by Scott Guthrie here.
I don't want this to sound like I am saying anything bad about this former colleague of mine. He's a very sharp person and an excellent developer. I'm confident that he will use this technology appropriately, but at the same time there are other options, and the statement just caught me way off guard.
Of all the new things to get excited about, extensions methods would have been near the bottom of my list. In fact the only reason they aren't at the absolute bottom is because of the wonderful new feature known as partial methods (More on that another day).
Honestly, extension methods scare me half to death. The existence of extension methods and the previously mentioned partial methods scare me so bad I could see myself recommending holding off on .NET 3.5/C# 3.0 until a proper policing process is put in place.
In a quote on the Scott Guthrie blog, Scott made a true enough statement which said "When used correctly, I think you'll find that Extension Methods can significantly improve code comprehension within code reviews, and lead to fewer lines of code and fewer bugs." Now, that is fine and all, but I'm not worried about when they are used correctly, I'm worried about when every unqualified programmer gets his or her hands on this dangerous new technology. OK, so Microsoft needed extension methods to implement LINQ, I understand that, but couldn't we have maybe hidden it from other developers? Maybe we could have found another way?
If you are wondering why I'm so paranoid about this, it is because of the massive amounts of incomprehensible code I've seen in my life. I just see this adding to it. People who do not understand the purpose of extension methods, or have the judgment to properly determine when they should use them and when they should not use them are going to litter in our code.
In most applications I have worked on the String class plays a monumental role in our development effort. I can see it now where a developer gets it in his or her head that we need mountains of extension methods written on the string class. Now you may say to me, "You'll only see them if you include that namespace though". Well, I can see these same developers saying "It's such a pain to have to keep adding a using statement to my code files when I want these awesome string extension methods everywhere! I'll just put in the the System namespace, then it'll always appear for me! Just imagine code where you could use a string for anything. Every conversion method imaginable can live on the string. The string class will have the ToInt32() method, the ToInt64() method, the ToDecimal() method, then it will get even more fun when we start seeing things like ToOrder() where the extension method will convert the string to an Order number then load the Order object from the database and return it. The possibilities are limitless!
Let's not pretend like we haven't seen developers use the string object for way more than it is supposed to be used for. I've already had to put up with it used as a rounding mechanism, if we just take a decimal/double output it to a string with two decimal places, and then parse it with the decimal/double class we'll have a rounded number to two decimal places! What if I just want a DateTime object with the date value but a time of midnight? Since I don't know about the Date property of the DateTime I might as well use the ToShortDateString() method and then DateTime.Parse() to get the new DateTime value back without a time! What could be more awesome? Can't you see these same people using the new extension methods to shoot themselves in the foot?
We'll have code reviews only to find their code is near impossible to read. A senior developer may write a library to be used throughout the application to keep things consistent, scalable, reusable or otherwise in line with the goals of the company/team, only to find that another developer though it needed some new methods which completely violate the interface of the library. Now other developers start seeing these new methods in their intellisense thinking they are part of the library, only to later find out that any code written using these extension methods now needs to be re-written.
I've had developers change core libraries on me before where they had no business doing such. I previously built a system where every message returned from our business objects was associated with a code in an enumeration. This enumeration is then used to look up the appropriate message depending on the culture/language of the user (Even if the initial releases only had English) when displayed. Developers though this was "inconvenient" and too time consuming, so what did they do? They added a new message type where you just provide the string you want to display (in English) and a generic message code like "Error". Wow, now it is so much easier to write these business object methods!
Now this was easy enough to catch, and in all honesty probably an honest mistake where they didn't properly understand why we were doing what we were doing. I fear extension methods are just going to make things like this harder to catch!
Why do we need the extension methods when we can just use the static class utility methods instead? You want to have some one off method to check for the validity of a string as an e-mail address, but don't want to write an e-mail class? How about an EmailUtilitity static class with a static method IsValidEmailAddress(string email)? Now instead of writing
you instead write
What is so horrible about that syntax? To me it is far easier to read, more maintainable and what most of us are already used to! Just about any use I can think of for an extension method can be written this way instead, and that's how I would prefer to see it.