Extension Methods, Fluent Interfaces, and the evils of API Pollution

I am going to propose a guideline for the use of C# 3.0 Extension Methods: Don’t Use Them to Rename Existing Functionality in an API Just Because You Don’t Like A Function’s Name.

The idea of extension methods is that you can improve an otherwise non-extensible object’s public API by ‘extending’ its Interface to include additional methods that the original class designer hadn’t considered.  Used judiciously, this technique can improve the usability of the object and make interacting with it much more intuitive.  Common uses are in the areas of aggregating what would otherwise be calls to multiple separate methods into a single ‘meta-method’ that wraps several more atomic methods, providing ‘converter’ methods that handle type conversions, and wiring up external validation logic to an object.

But all too often lately I am seeing these methods used simply to provide alternate preferred names to existing methods already present in the original class.

Unit Test Frameworks should remain Pure

This is probably most-commonly seen in (of all places) Unit Test frameworks.  For a long time there was (general) agreement among both designers and users of Unit Test frameworks about the ‘common’ way to state assertions.  Or at least I thought there was general agreement.  Apparently, it seems that this ‘agreement’ may have just been a consequence of people not having an easy way to deviate from the commonly-accepted norms.

Today in all kinds of sample code in various blog posts all over the Internet I routinely see things like…

Assert.AreEqual(expected, actual);

Assert.Equal(expected, actual);

Assert.That(expected, actual).AreEqual();

Assert.That(actual).ShouldEqual(expected);

Even if reasonable people can debate the ‘best’ way to state an equality assertion in a unit test framework, I firmly believe that the place for this debate is between the team maintaining the unit test framework project and its user-base, NOT between different adopters of each Unit Test Framework by randomly inventing extension methods that provide the exact same capability as already present in the framework.

Technology isn’t evil, but its implementation sure can be

This isn’t to say that I don’t like fluent interfaces and don’t like extension methods.  These are just techniques and technologies like any other that can be used either for good or evil at the whim of the developer who wields them.

But when used to arbitrarily restate behavior that already exists on a class in an alternate syntax just for the sake of a very limited (and entirely debatable) improvement in readability, I think reasonable people have to agree that this is leading us down a road towards what I call API pollution where three and four methods on a single class all do the exact same thing but use a slightly different syntax to accomplish it.

Assert.That(actual).Should().Nearly().Equal(expected).Except().When().Varying().By().LessThan(3);

…is the inevitable end-result of this trend and I for one don’t want to try to be a consumer of such a framework, no matter how ‘readable’ it was thought to be.