jump to navigation

Extension methods – do or do not? Monday, 03/04/2013

Posted by Percy in Programming, Technology.
1 comment so far

I was in a recent code review at work, and we came across the following code which pre-dated the current release. So, it technically wasn’t up for review, but it sparked an interesting discussion.

public static class Extensions
{
    public static bool IsNullOrEmpty(this string input)
    {
        return string.IsNullOrEmpty(input);
    }
}

In the interest of full disclosure, I think that this method (along with a few others) should be part of the .NET framework. So, I’m actually a fan of having a method like this in the project I’m working on.

However, not everyone in the code review I was in was a fan of having a method like this. I think there are some valid concerns about the use of extension methods – just like with any tool out there. You can use a great tool in the wrong way and have disaserous results. So, what comes next, while a defense of this particular situation, may not apply to all use of extension methods.

As I’ve stated before, everyone is entitled to their opinion. I just like to back mine up with some of my reasoning. You’re welcome to agree or disagree.

Here’s my main contention – I think extension methods allow you to write code that is more readable, and also allows you to write less code by making reusable methods.

In this case, I think this extension method, while just really a wrapper around another method, actually makes the code more readable. It allows you to write code that can be easily read by those that might not even be developers. So, adding this extension method, you can do something like this:

string name = "My Name";
if(name.IsNullOrEmpty())
{
    // Do something
}

To me, that reads “If name is null or empty, do something” – fairly straightforward. Now, not having the extension method doesn’t add more lines of code. So, without it, you would have this:

string name = "My Name";
if(string.IsNullOrEmpty(name))
{
    // Do something
}

Honestly, I tried to come up with a simple sentence that follows that code layout, and I couldn’t. The best I could come up with is “If a string value is null or empty represented by the variable name, do something”. I’m not even sure if that’s grammatically correct. Again, the code doesn’t really function much differently. In this case it’s all just in how the code looks. However, I think the code with the extension method has an advantage over the one without.

There’s another example that we’ve used a lot. It’s an extension method that I’ve added to a number of projects, that I think should be part of the framework.

public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
    if(source != null && action != null)
    {
        foreach(T item in source)
        {
            action(item);
        }
    }
}

This allows you to do things like this:

IEnumerable customers = Customer.GetAll();
customers.ForEach(c => Console.WriteLine(c.Name));

Without the extension method, the same code would be:

IEnumerable customers = Customer.GetAll();
foreach(Customer c in customers)
{
    Console.WriteLine(c.Name);
}

So, it’s not a complex example, but two lines of code with the extension method become five without it. Even given that the bracket lines are unnecessary since you only have one line, that still is three lines of code against two in the original.

Also, one powerful feature that extension methods have over regular methods is that you can actually and successfully call extension methods “on” objects set to null. Since the method is actually static, and it’s not actually being called from code inside the object, you can do a null check on the “this” object and handle things appropriately. So, you can do something like this:

IEnumerable customers = null;
customers.ForEach(c => Console.WriteLine(c.Name));

In this case, the code just won’t do anything, but it won’t throw a null reference exception. Since I check for null in the extension method, it’s handled.

There are some downsides to Extension methods, however. I’m a believer that the benefits outweigh the issues, but I feel it’s at least appropriate to throw those out there.

So, it can get confusing that you’re calling methods that actually don’t exist within the object itself. You might think that the base string object always has an “IsNullOrEmpty” method, so any string in any project can use it and that might not be the case. It would only be available in those projects where the extension method is available and the namespace references. Also, in versions of C# 3.0 and higher, you can actually have instance methods and extension methods on the same object with the same signature. In that case, the instance method will be given priority. However, that could get confusing if you’re expecting the extension method to be called, and you can’t seem to figure out why it’s not being called.

I’m sure there are other issues with extension methods that I’m leaving out. What’s your opinion? Extension methods – do or do not?

Advertisements
%d bloggers like this: