The Power of Extension Methods

September 8, 2020 By Nick Proud

Changing code. It’s a minefield. If you’re attempting to abide by the laws of the Open Closed Principle, we want to avoid changing previously written code wherever possible, in favour of extending our codebase with new functionality. This allows us to hopefully minimise the number of bugs we inadvertently introduce to our codebase.

Keeping existing code open for extension and closed for modification can be tricky, which is where Extension Methods arrive to save the day.

Extension Methods allow us to add functionality to already existing types without the need to modify anything within the type, or the need to recompile. It literally allows us to ‘bolt-on’ functionality to an existing class.

If you’ve written any .NET code, it’s likely you have used ‘ .ToString()’ at least once. Extension methods in appearance are pretty much the same as this. You have an existing class to which you wish to add functionality. You call the extended functionality by adding a dot (‘.’) to the end of the class name and then calling your extension method. But how do we create an extension method?

A C# Extension Method

To create an extension method, you need to make a static class. Depending on how many extension methods you have or what they apply to (i.e what sort of functionality they extend) you can have a single class with multiple extension methods or a single class for each kind of extension you wish to implement.

For this example, I’m going to simply create a static class called ‘ExtensionMethods.’ Within this, I’m going to extend the .NET ‘String’ object to return true or false if there are an even number of characters in the string.

For context, this would allow us to do the following:

            string myString = "Hello World";
            bool isEvent = myString.CharacterLengthIsEven();

So lets build this extension method.

First create a class for the method to live in. It should be a static class

using System;
using System.Collections.Generic;
using System.Text;

namespace TestConsole
{
    public static class ExtensionMethods
    {
      
    }
}

Create a function that returns your intended data type. (In our case a bool defined as true if the string we are targeting has an even number of characters.) The function should also be static.

Add a parameter to the method in the form of a string. You’ll notice that we also use the ‘this’ keyword before the parameter. This is how we state that the method extends the ‘String’ object.

 public static bool CharacterLengthIsEven(this string str)
 {
           
 }

We now have a method which extends ‘String’ but it will not compile as we are not returning anything. We need a method body; a place where the check for an even number of characters is carried out.

 public static bool CharacterLengthIsEven(this string str)
 {
     return str.Length % 2 == 0;
 }

We don’t need to go into too much detail about how we implemented the above, as this guide aims to explain how to create extension methods, not how to build the logic within them, but sufficed to say, the below line of code will check the incoming string argument (the value of the string we are extending) to see if there is any remaining value in the character length when it is divided by two using the remainder operator. If the result is 0, the number was wholly divided by 2 and is therefore even.

And that’s it! We have a simple extension method that we can use to check whether a character length of a targeted string is odd or even.

 string myString = "Hello World";
 bool isEvent = myString.CharacterLengthIsEven(); 
//result will be false as there are 11 characters in the length of 'myString'

So why did we do this rather than just writing a function? Well it’s largely a matter of preference, but the main benefits I think we enjoy from extension methods are (as mentioned earlier) an adherence to the Open Closed Principle, allowing us to extend the feature-set of an existing type without modifying existing code, as well as keeping functionality loosely coupled, segregated away from our main types.

It can also come across as easier to read, as you are not passing functions around as values, instead opting to chain ‘.myExtendedFunctionality()’ on to the end of objects you wish to manipulate.

Whichever way you look at it, it’s arguably a good skill to have in your armoury, especially considering the low amount of effort and difficulty that comes with implementing these methods.

As with anything new in code, you learn by doing of course. So get extending!

Share