Extension Methods Refresher

I see a lot of questions on places like stack overflow, code project, and Lidnug. A lot of these questions are simple questions for simple routines, the type of routine that would easily fall into the class of "Utility Library Routine." Time and Time again, question after question, the same ones pop up over and over, and I got to wondering why.

I mean, why do these questions have so many duplicate answers? Then, it hit me.

It's because a lot of developers, especially those just starting out, are not taught the core principles of code re-use. They're taught encapsulation, which is fine, but they get taught encapsulation from an "I'm designing an API" point of view, then don't get taught, "Hey, see all those useful little routines you're building, you can encapsulate those too and re-use them later on."

If any of this is old news to you, please be aware this article is aimed at those relatively new to .NET.

Encapsulation for the Masses

.NET makes it amazingly easy to re-use a lot of these routines you develop through the use of something called "Extension Methods."

You've no doubt already used them, but without realizing. For example, when you use LINQ, you might do something like the following:

List<myObject> myObjects =
   new List<myObject>{ new myObject(),
   new myObject(), new myObject() }

Then, later on, you might do something like this:

var singleObject = myObjects.FirstOrDefault();

When you call this "FirstOrDefault" method, which appears to be part of your object list class, you're actually calling an extension method. In this case, it's an extension method on the "List" class, but there are many more, such as "Select" and "Where" that are actually called on each object in the list, all without you having to write any looping code.

Although this is strictly not encapsulation (at least not by the definition of Object Orientated practices), it is nevertheless a great way to wrap your extension functionality up into re-usable libraries that you can then use in future projects.

How Can I Make Use of This Myself?

It's really easy to make your own extension methods. All you need to do is build a static class with static methods where the first parameter of the method is the type you want to extend.

Let's imagine you wanted to print a string using angle brackets, something like:

[This is my string]

You could extend the string class with an extension method to do this, by using the following code:

public static class StringExtensions
   public static string WithBrackets(this string s)
      return "[" + s + "]";

To use it you can then simply do something like:

Console.WriteLine("This is my string".WithBrackets());

and you'll get a string that has square brackets surrounding it. This, however, was not a particularly useful example, but it illustrates the usefulness of the extension mechanism. Let's try one more:

public static class IntegerExtensions
   public static TimeSpan Hours(this int i)
      return new TimeSpan(0, i, 0, 0);

This now allows you to get a time span value by using

var dayLength = 8.Hours();

Because it returns a time span object, any extension methods that the time span objects use can also be chained onto that. As well as that, anything that understands a time span can also use the output of this extension.

For example:

var finishTime = DateTime.UtcNow + 8.Hours();

Not only are you creating extensions that are reusable at all levels, but you're also making the code you write much more readable and easier for other developers to follow, too. Extension methods can be created on any object, whether you have the original sources for that object or not.

As you've seen above, I've already presented two examples that extend the built-in .NET types. If you have a third party library that you use often, one that's perhaps a bit cumbersome to use, you can easily redefine the semantics of its usage without ever knowing what's going on under the hood.

Remember, too, that you don't have to do simple things. It's feasible to put quite complex logic into an extension and encapsulate that logic into a simple chained call. By way of a theoretical example, imagine the following:

var dataObjectOne =
   new myDataObject.GetFromDatabase();
var dataObjectTwo =
   new myDataObject.GetFromWebservice();

You can easily wrap the murky details of your database and web service access code inside simple-to-use extensions. All that matters is that the objects are created and valid.

If there's something you'd like to know about .NET, or any of its available classes, feel free to leave a message in the comments below and I'll see what I can do, or come find me on Twitter as @shawty_ds and ask me there.

Related Articles


  • Extention naming question

    Posted by Stephan on 02/23/2015 12:27am

    Since you use "My..." naming for first example, and "StringExtension", "xxxExtension" for other examples, I get the impression that "StringExtension" MUST use this naming convention? Is that correct? I realize it's good practice to have a clear name, but I can't tell if it's required or recommended here. For example, if you had said "MyStringExtension", it would have been clear to me that the name was something I could choose, and then "it's recommended to use "Extension" for standard class extensions. Please clear this up for me? Thanks!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • As all sorts of data becomes available for storage, analysis and retrieval - so called 'Big Data' - there are potentially huge benefits, but equally huge challenges...
  • The agile organization needs knowledge to act on, quickly and effectively. Though many organizations are clamouring for "Big Data", not nearly as many know what to do with it...
  • Cloud-based integration solutions can be confusing. Adding to the confusion are the multiple ways IT departments can deliver such integration...

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date