Extension Methods and Helper Classes as Design Elements

by Larry Spencer Tuesday, June 26, 2012 6:00 PM

This is the second in a series on ways to make classes relate to each other or to themselves. Last time, we considered partial classes. (I wasn't too keen on them.) This time, we will look at extension methods and static helper classes.

Static Helper Classes

A static helper class is a collection of related static methods. (They ought to be related, anyway.) For example, I have a DatabaseHelper class in my library of test utilities with methods like CreateDatabase, DropDatabase, and ExecuteScalar. Each one is just a convenience method that wraps up a few lines of code, saving me from having to repeat it.

Static helper classes are a very humble design element. They hide no data, do not inherit anything, and do not implement an interface. They are just there to help. There is nothing wrong with that, provided they are organized and cohesive. In fact, when a helper class is so cohesive that all of its methods relate to one class, we open the way for a little miracle that came with C# 3.5...

Extension Methods

In effect, extension methods let you add methods to a class even if you don't have the source for that class. But they do more than that: you can add methods to an interface, to a built-in type, even to an enum.

You can read about how to create them on MSDN; this post is about why and when you would want to create them.

As with partial classes, good, old-fashioned SOLID principles are our faithful guides. In particular, just because extension methods let us add almost any capability to a class, does not mean that we should violate the Single Responsibility Principle.

LINQ's extension of IEnumerable<T> is exemplary. Just as it is natural for there to be an addition (+) operator on the int type, a Concat method is a good fit on IEnumerable<T>. LINQ provides it via an extension method. 

Extension methods can also be abused. Suppose you have a data-transfer object (DTO) whose members you wish to display on an ASP.NET Web Form. You've read about extension methods and think, "I know what would be cool! I could add extension methods to my DTO so it knows how to display itself on a form!" That would be bad. The DTO's single responsibility is to transfer data from one subsystem to another. It is not supposed to know anything about displaying itself, no matter how object-oriented the idea may sound. The fact that you're using a cool .NET 3.5 feature doesn't make it right. ;)

An interesting use of extension methods is to provide something like multiple inheritance. In .NET, you can inherit from only one class, but from multiple interfaces. There's nothing to stop you from providing extension methods on those interfaces. That will make them sort of like classes. Voila! Multiple inheritance! (Sort of.) 

Guidelines for Extension Methods

Cwalina and Abrams' book, Framework Design Guidelines, offers these rules for extension methods.

  • Avoid frivolously defining extension methods, especially on types you don't own.
  • Consider extension methods to provide functionality to every implementation of an interface. LINQ's extensions on IEnumerable<T> are an example.
  • Consider extension methods to avoid dependencies you don't want. Cwalina and Abrams give an example. You don't want the String class to depend on System.Uri, but you could extend String with a ToUri method that converts the string to a Uri.

They have further suggestions, such as what namespace to put your extension methods in. Check out the book for more.

Conclusion

Extension methods are good for providing pseudo-multiple-inheritance and for avoiding unwanted dependencies. Beyond that, keep an eye on the Single Responsibility Principle.

Tags: ,

All

About the Author

Larry Spencer

Larry Spencer develops software with the Microsoft .NET Framework for ScerIS, a document-management company in Sudbury, MA.