RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Building Truly Useful Extension Methods  : Page 2

Use extension methods to breathe new life into old classes—even classes that you didn't write!

Simple String Extensions
To create an extension method, you really only need to perform two steps. What those steps are depends on whether you're using Visual Basic or C#.

Creating Extensions in VB
  1. Flag a subroutine or function with the Extension attribute. Extension is defined in the System.Runtime.CompilerServices namespace so you may want to import that namespace to make using the attribute easier.
  2. Write the subroutine or function. The only trick here is that the first parameter to the method is the object on which it is acting. For example, if you're making an extension to the Customer class then this method's first parameter must be a Customer object.
How about a useful example? Do you remember Visual Basic 6's Right function? It returned a certain number of characters from the right end of a string. To do the same thing with the modern String class you need to use the Substring method and the string's Length property to calculate where to start extracting characters. It's not terribly hard but getting it right does require some thought.

The Right function is useful in a wide variety of circumstances, fits well with other String methods such as Substring, and doesn't overload an existing method in a confusing way, so it makes a nice addition:

   Imports System.Runtime.CompilerServices
   Module StringExtensions
      ''' <summary>
      ''' Return the rightmost number_of_characters characters
      ''' from the string.
      ''' </summary>
      ''' <param name="str">The string being extended</param>
      ''' <param name="number_of_characters">The number of
      ''' characters to return.</param>
      ''' <returns>A string containing the rightmost characters
      ''' in this string.</returns>
      ''' <remarks></remarks>
      <Extension()> _
      Public Function Right(ByVal str As String, _
      ByVal number_of_characters As Integer) As String
         If str.Length <= number_of_characters Then Return str
         Return str.Substring(str.Length - number_of_characters)
      End Function
   End Module ' StringExtensions.
This code satisfies the requirements for an extension method.

  • It begins by importing System.Runtime.CompilerServices so it can easily use the Extension attribute.
  • The code incorporates the newfangled "triple-tick" (''') comments to describe the function's purpose and parameters. That syntax lets IntelliSense read the comments and display them, showing what the code does and what its parameters are, so others trying to use this method get the information they need. Using comments effectively goes a long way toward making hidden extension methods easier to understand and use.
  • The extension method is decorated by the Extension attribute and declared as a public function. Its first parameter is a String, so that is the class that it extends. The code that uses this method should pass the remaining parameter into the method call.
The body of the routine ensures the string is long enough, and then performs the simple (but annoying) calculation to return the rightmost characters.

Here's how a program might use the new String.Right extension method:

   Dim txt As String = _
      "What kind of noise annoys a noisy oyster?"
   Dim word As String = txt.Right(7)
This code initializes the string txt and then calls its Right extension method. Internally the .NET framework passes the string itself (txt) as the first parameter to the method and the value 7 as the second. The method uses the string's Substring and Length methods to peel off the specified number of rightmost characters and returns them, filling the variable word with the value "oyster?"

Creating Extensions in C#
In C#, things are a little different. C# doesn't allow you to write code that isn't part of a class and—let's face it—sometimes code just doesn't belong in a class. (In this case, the code really belongs in someone else's class that you didn't write and whose code is hidden from you.) So in C# you do the next best thing:

  1. Create a static class in which to put your static extension.
  2. Just as in Visual Basic, you then write the extension method. The difference is that C# doesn't require the Extension attribute. However without the attribute, how is C# supposed to know that this is an extension method? The answer is that you give it the needed hint by placing the keyword this in front of the first parameter's declaration. That parameter specifies the type of the class you are extending.
The following code shows the C# version of the Right extension method. You'll find it in the downloadable program example in the CStringExtensionsDemo namespace, inside the static class StringExtensions. Note that the method is also static and that it uses the this keyword to indicate that it is an extension method.

   namespace CStringExtensionsDemo
      static class StringExtensions
         public static String Right(this string str,
            int number_of_characters)
            if (str.Length <= number_of_characters) return str;
               str.Substring(str.Length -- number_of_characters);
Author's Note: This all seems kind of kludgy to me. You have to read the code pretty carefully to notice that this is an extension method. I think I prefer the Extension attribute.)

More Useful Extensions
Now that you've seen how to write the Right method, it's easy enough to add similar methods. The following VB code shows a Left extension method that returns the characters on the left end of a string. (I'm leaving out the triple-tick comments to make the code easier to read.) The code also shows RemoveLeft and RemoveRight methods that strip off the leftmost and rightmost characters from a string. (Those two are a bit gratuitous, but I still maintain that they're more useful than a palindrome checker! Plus this is all just warm-up for the excitement yet to come.)

   ' Return the leftmost number_of_characters characters
   ' from the string.
   <Extension()> _
   Public Function Left(ByVal str As String, _
   ByVal number_of_characters As Integer) As String
      If str.Length <= number_of_characters Then Return str
      Return str.Substring(0, number_of_characters)
   End Function
   ' Return the string with the leftmost
   ' number_of_characters characters removed.
   <Extension()> _
   Public Function RemoveLeft(ByVal str As String, _
   ByVal number_of_characters As Integer) As String
      If str.Length <= number_of_characters Then Return ""
      Return str.Substring(number_of_characters)
   End Function
   ' Return the string with the rightmost
   ' number_of_characters characters removed.
   <Extension()> _
   Public Function RemoveRight(ByVal str As String, _
   ByVal number_of_characters As Integer) As String
      If str.Length <= number_of_characters Then Return ""
      Return str.Substring(0, str.Length - number_of_characters)
   End Function
Such simple extensions are useful, but the real power of extension methods lies in encapsulating more complex code, making it available through into Intellisense at a developer's fingertips.

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