C# extension methods design patterns and usage guidelines

.net coreasp.net-corec

C# extension methods have seen a rise in usage over recent years. The offical microsoft guidelines on usage state: "In general, we recommend that you implement extension methods sparingly and only when you have to" The extension method guidelines.

On the other hand Microsoft are now using them heavily in dot net core (see the microsoft extensions name space).
This is particularly prevalent is asp core where the initializaion of the IServiceCollection is implemented in extension methods, for example see The service collection service extensions. Dot net core tutorials has an article listing this as a design pattern suggesting that it is best practice. Quite a few popular nuget packages also use this method to initialise services: Swagger is configured this way microsoft docs as well as mediatr their implementation

Should the guidelines be updated or should this practice be avoided?
If the guidelines are to be updated what should they be?

Best Answer

Extension methods are just syntactic sugar for ordinary static method calls.

Extension methods make possible the ability to "spot-weld" methods onto existing types, without requiring inheritance, composition, weaving or any other language mechanisms. But they're just a proxy for an ordinary method call; they don't participate in the design of the class, nor do they add any new functionality that the class doesn't already have.

What an extension method does is turn this:

Manager.Foo(bar);

into this:

bar.Foo();

And that's all it really does.

It's arguably prettier (which is no small thing), but really, is there any other compelling reason to use extension methods?

Yes: to enable Method Chaining.

var productList = products
   .Where(prod => prod.StateOfManufacture = "CA")
   .OrderBy(prod => prod.Category)
   .ThenByDescending(prod => prod.UnitPrice)
   .Select(prod => new 
        { Name = prod.ProductName, Category = prod.Category, Price = prod.UnitPrice });

This would be very tedious without extension methods.

The advice "use extension methods sparingly, and only when you have to" is not actionable. Entire libraries and frameworks have been built using extension methods, and you never "have to."

So is it a "best practice?" My answer to that is "does it most effectively meet your specific needs?"