I have had the opportunity to spend some time attempting to unravel work on an application recently that has been written to take extensive advantage of extension methods (no pun intended).  With the introduction of extension methods Microsoft handed developers a very powerful tool, but one that is very easy to abuse.

As soon as extension methods were released, people started using them to enable quasi-multiple inheritance in a “mixin” type approach.  The problem with this type of architectural approach, although very powerful, is the complexity and high entry-level to debug, enhance and maintain such a codebase.

As an (abbreviated) example, say you have a class extending a base class:

using System;

namespace Test
{
    public class SomeOtherClass : BaseClass
    {
        public void SomeOtherClassMethod()
        {
            Console.WriteLine("SomeOtherClass");
        }
    }
}

And your base class looks like this:

using System;

namespace Test
{
    public class BaseClass : IFoo, IBlah, IWhatever
    {
        public virtual void BaseClassMethod()
        {
            Console.WriteLine("Something");
        }
    }
}

With the help of a bunch of extension methods hanging off the interfaces, you can do this:

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            SomeOtherClass someOtherObject = new SomeOtherClass();
            someOtherObject.BlahExtensionMethod("test");
            someOtherObject.FooExtensionMethod("test");
            someOtherObject.WhateverExtensionMethod("test");
            someOtherObject.BaseClassMethod();
            someOtherObject.SomeOtherClassMethod();
        }
    }
}

So, where is the damn code huh??? Its certainly not in the class you instantiated. You can F12 around via the IDE to find the methods, but there is no standard approach to the naming or location of the actual class files that include the code. The above is a simple example, and you have code in five different places for one class! On top of that, the compiler binds differently to extension methods and methods on a concrete class, so you can even get into situations where you have to apply a rule hierarchy to even guess which code will actual be called. Microsoft’s advice?

In general, we recommend that you implement extension methods sparingly and only when you have to.

The heavy architectural use of interface extension methods may in time become the expected and excepted approach to architect C# functionality and provide a more powerful approach to code reuse and class definition, but before then I think we will see a lot of people experimenting with different implementation approaches. I think I am looking at one of those experiments. And its making my head hurt. I couldn’t even guess how many open code windows I would need open to actually see the full implementation of a class. Its not as if coding wasn’t hard enough already without hiding the damn code!

You could successfully argue that advanced techniques like this aren’t meant for plebs like me, and I would probably agree. Of course, I would argue right back at you that in all probability your code is going to be maintained by the belly of the bell curve, not the high order standard deviation you obviously exist in, and your code is going to end up costing a lot more money to maintain if it is as baroque and obscure as the interface extensions pattern can become. Worth reading the “Maintenance” section of “Frequently Forgotten Fundamental Facts about Software Engineering” by Robert L. Glass as a quick refresher as to why you should care about maintenance cost and code complexity. Importantly:

M5. Most software development tasks and software maintenance tasks are the same—except for the additional maintenance task of “understanding the existing product.” This task is the dominant maintenance activity, consuming roughly 30 percent of maintenance time. So, you could claim that maintenance is more difficult than development.

Hopefully in the end some hard and fast rules around namespaces, file naming, and structure will emerge, and someone needs to keep experimenting with these patterns until something less painful solidifies….just hopefully not on any code I have to deal with.