DEV Community

Cover image for Using Extension Methods in C# to Build Fluent Code
Matt Eland
Matt Eland

Posted on • Originally published at killalldefects.com on

Using Extension Methods in C# to Build Fluent Code

Extension methods are an integral part of modern .NET and some of .NET’s best features such as LINQ. Unfortunately, a lot of developers get intimidated by them and don’t understand what’s going on under the surface or how to build new ones. In this article I’ll attempt to demystify extension methods and illustrate how they can be used to build elegant and fluent code.

The Basics: Static Methods

In order to discuss extension methods, we have to first discuss static methods.

A static method is simply a method declared with a static keyword. This tells .NET that the method operates not on a specific instance basis, but is attached to the class as a whole. Since these methods are static, they do not have access to the state of any specific instance unless it is passed in as a parameter to the method (more on this later).

The Integer.Parse method is a fairly well-known static method as is String.IsNullOrEmpty.

Over the course of this article we’ll be building out a method for getting information on books, so let’s create a static method that builds a list of books.

Now, to call out to get our books, we just do something like this:

var books = Books.GetBooks();

Pretty simple to use.

Extension Methods

Next let’s turn our attention to extension methods.

Put simply, extension methods are specially declared static methods that the compiler lets you call on objects matching their signature.

Let me show you what I mean.

Let’s say we have the following static method:

Here we can take any Book instance and pass it in to Books.IsBoring and get a boolean response.

Let’s change this to be an extension method.

Since extension methods can only be declared in static classes (classes which cannot be instantiated and have only static members), we need to add the static keyword to our class.

Now, we declare our IsBoring method to be an extension method by adding the this keyword to the first parameter like so:

What the this keyword is telling .NET is that IsBoring is an extension method and can either be invoked via the static method syntax like Books.IsBoring(someBook) or via an extension method syntax like someBook.IsBoring().

Note that the this keyword in the extension method syntax can only be used for the first parameter, which is the type or interface that the method extends.

Extension methods are syntactic sugar to have the compiler replace extension method style invocations to static method invocations.

The net result, however, is that extension methods let you appear to bolt on new functionality to other classes or interfaces. This is their primary advantage as extension methods allow you to simplify calling syntax at the cost of obscuring exactly where the method is declared to the casual reader.

Now that we know what extension methods are, let’s look at using them to build a fluent syntax or domain specific language.

Chaining Extension Methods Together

Let’s say you want to create a book and need to perform a number of operations in order to create a valid book. If you wanted to offer a fairly flexible and readable API, you could use extension methods to create a mini domain specific language (DSL).

In this example, our end goal is to create a book object that is customized based on the values we’ve configured.

Let’s focus on the end result first:

There’s a lot going on there, but maybe not as much as you think.

Let’s start with the Books.CreateBook call. This is a static method invocation that takes in a string representing a book’s title and return’s some mystery object.

Let’s call that object a BookBuilder and say that it looks something like this:

Okay, now this is making maybe a little more sense. That’d mean that our CreateBook static method would look something like:

Next our example has us calling WrittenBy. Well, the BookBuilder class doesn’t define that method. In a normal application we’d probably just add the method to BookBuilder, but that wouldn’t let us play with extension methods here, so let’s pretend that the BookBuilder class is defined by some code we don’t control and can’t modify.

We’ll handle the WrittenBy method by adding an extension method:

This is a very simple method, but there’s some key things going on here.

First, the method acts as an extension method on BookBuilder instances due to the this keyword in the parameter signature.

Second, the method is invoked with only one parameter specified (e.g. WrittenBy("Michael Crichton") because the first parameter is inferred based on the BookBuilder you’re invoking the extension method on.

Third, we’re returning the same builder instance we got back. The reason why we return this parameter is entirely to support fluent syntax like we saw in the example earlier, and allow invoking extension methods on the return result of prior extension methods.

The final static class might look something like this:

That might not look like the prettiest code you’ve ever seen, but the type of syntax it can create can be incredibly powerful and beautiful.

Let’s Talk about LINQ

Extension Methods were added to the C# language explicitly in order to support L anguage In tegrated Q uery (LINQ) in .NET Framework 3.5.

LINQ is one of my favorite features of C# in terms of developer productivity, and none of that would have been possible without extension methods.

LINQ lets you do things like:

Maybe this is a little bit of a silly example, but this all works by having extension methods that take in IEnumerable<T> or IQueryable<T> and use various Func signatures to filter, sort, or transform the collection.

Put another way, if you really wanted to, you could write your own version of LINQ with about the exact same syntax using extension methods. Please don’t do this – Microsoft did a great job already – but the capabilities of extension methods allow you to do this.

Closing Thoughts

Hopefully this demystifies some of the magic behind extension methods, LINQ, and static vs instance methods.

I am convinced that extension methods (and LINQ by extension) are one of the key productivity gains of .NET technologies, alongside things like the base class library, the common language runtime, Visual Studio, and generics.

While you may not create or even think about extension methods, they power a lot of what we do in modern .NET and the flexibilty they offer can be a tool for good.

The post Using Extension Methods in C# to Build Fluent Code appeared first on Kill All Defects.

Top comments (12)

Collapse
 
silviosavino1 profile image
Silvio Savino

Great article but what do you think about the allocations caused by LINQ?

As a game programmer I've been taught to avoid using LINQ, especially in scripts running in real-time on the main thread in order to avoid allocations and so sudden frame drops caused by the GC kicking in. Surely a game is not comparable to other types of programs and besides not every LINQ method necessarily allocates (I sincerely don't know). Maybe some of the allocations could be even avoided, like those caused by the Func passed by simply caching them, but then it would lose in readability.

It's a tool like many others .NET put you at your disposal but would you still suggest it for environments like games?

Collapse
 
integerman profile image
Matt Eland

I use LINQ by default. However, I did find while profiling a roguelike's core AI routines that LINQ significantly added to the duration of the application. However, this was a core routine in a genetic algorithm that had to run millions of times.

My suggestion would be to go with LINQ until your data tells you to avoid it in key places, then make those optimizations.

Collapse
 
vasar007 profile image
Vasily Vasilyev

Next our example has us calling WrittenBy. Well, the BookBuilder class doesn’t define that method. In a normal application we’d probably just add the method to BookBuilder, but that wouldn’t let us play with extension methods here, so let’s pretend that the BookBuilder class is defined by some code we don’t control and can’t modify.

(I emphasised the main purpose)

Collapse
 
integerman profile image
Matt Eland

It's a very valid question. The answer is "I need to teach extension methods". If you have full control of all code, you're better off putting it in BookBuilder.

Collapse
 
rafalpienkowski profile image
Rafal Pienkowski

Nice post.

I’m a fan of the Extension methods. Like in your examples, I combine them with the Builder pattern too. I think that this combination creates a readable Domain Specific Language (DSL) that could be used in the test case scenarios for an application. With such a DSL, we can build our System Under Test (SUT) in a very descriptive way.

I can't wait for your next article.

Cheers.

Collapse
 
integerman profile image
Matt Eland

I've done that before and really like the power and simplicity of that, plus the way it makes tests more maintainable. I really should write about that at some point soon.

Collapse
 
loopdeez profile image
Loopdeez

Great post Matt. Clearly explained and absolutely useful!

Collapse
 
somedood profile image
Basti Ortiz

Cool! This article further solidifies my love for the Builder Design Pattern. It's one of the best ones out there, to be honest.

Collapse
 
roguecode profile image
John Breland

Thanks for the introduction to Extension methods. You packed some great information in there and in a easy to follow and understand way.

Collapse
 
aminmansuri profile image
hidden_dude

Slowly slowly languages incorporate more Smalltalk features and style.. and still fail to be as clean and expressive.

Collapse
 
tyrrrz profile image
Oleksii Holub

If you're ready to take it unto the next level, check out how you can use extension methods in some more creative ways.