1. Home
  2. Computing & Technology
  3. Visual Basic

Using Extension Methods in VB.NET
Code your own method in just about any class!

By , About.com Guide

Sep 19 2009

Extension Methods were introduced in VB.NET 2008 primarily to support LINQ - Language Integrated Query. But they open up a whole new dimension of programming possibilities by themselves. This article tells you how to use them.

Here's a definition courtesy of Scott Wisniewski, a developer on the VB 9 Compiler Team:

"Extension methods enable you to create a method in a module decorated with an attribute and have that method appear as if it was an instance method defined on another type."

Huh!? Let's go through that a little slower.

If a method from another class is declared as "Shared" then you can use it in your code without creating an instance. For example:

Public Class mySharedMethod
   Shared Sub SharedExample()
      MsgBox("This method is shared" _
         & "No instantiation required.")
   End Sub
End Class

Private Sub Button1_Click( ...
   mySharedMethod.SharedExample()
End Sub

Otherwise, you have to create an instance of the class (in other words, an "object") to use the method.

Public Class myNonSharedMethod
   Public Sub NonSharedExample()
      MsgBox("This method is not shared" _
         & "An instance must be created.")
   End Sub
End Class

Private Sub Button1_Click( ...
   Dim nonShared As New myNonSharedMethod
   nonShared.NonSharedExample()
End Sub

Most of the time, this works great. It's only a problem when you need to modify a class that already exists. That's what Scott means by, "have that method appear as if it was an instance method defined on another type." "Type" is one of those words that gets used a lot but isn't really well defined. In general, it's almost the same thing as "object". The "type" of the variable "nonShared" above is "myNonSharedMethod". The "type" of "ABCDE" is String.

You can usually extend an existing class by inheriting it like this:

Private Class myInheritsExample
   Inherits myNonSharedMethod
   Sub newSub()
      MsgBox("From the newSub method")
   End Sub
End Class

Methods can be used from the original class and the new class now:

Private Sub Button1_Click( ...
   Dim myInherits As New myInheritsExample
   myInherits.NonSharedExample()
   myInherits.newSub()
End Sub

A class can be "sealed" and then it can't be inherited. In the example we will use, the Char type will be extended. Extension methods give you a way to add your own method to the Char class. For example suppose I decided to create a really simple minded cypher to protect strings from curious eyes consisting of simply subtracting 1 from the ASCII code for any character.

Public Function CharMinusOne(ByVal C As Char) As Char
   Dim ascCode As Integer = Asc(C)
   If ascCode = 0 Then ascCode = 255 _
   Else ascCode -= 1
   Return Chr(ascCode)
End Function

I can add this function to the .NET String class using extension methods. As Scott states, we first have to "create a method in a module decorated with an attribute". Note the limitation, "in a module" however. Because I wanted to clearly show what Shared and non-Shared methods were, I used a class in my code above. But extension methods can only be coded in modules. Since modules can't be instantiated (only classes can), you don't have to use the "Shared" keyword.

You might be unfamiliar with the term "decorated". As Scott uses the term here, it simply means that an "attribute" has been added to the code. Extension methods require a very specific one:

<System.Runtime.CompilerServices.Extension()>

The namespace "System.Runtime.CompilerServices" is often named in an Imports statement so only "<Extension()>" is needed.

With these details, here's the complete code for our extension method:

Namespace AVBStringNS
   Public Module AVBStringModule
      <System.Runtime.CompilerServices.Extension()> _
      Public Function CharMinusOne(ByVal C As Char) As Char
         Dim ascCode As Integer = Asc(C)
         If ascCode = 0 Then ascCode = 255 _
         Else ascCode -= 1
         Return Chr(ascCode)
      End Function
   End Module
End Namespace

The "Namespace" isn't strictly required, but it helps to guarantee that your extension method isn't confused with anything else. The Visual Basic team recommends the use of a namespace. If a name conflict occurs - and it's very possible because you often have no idea what else is in the class that you're modifying - the namespace identifies your new method. Remember that if the class you're modifying already has a method with the same name, the one in the class will always be used. As the Visual Basic team puts it in their blog, "any accessible instance member on a type will always shadow any extension methods with the same name."

The actual syntax of the extension itself only has one important rule: The type of the first parameter is the data type that is being extended. The first parameter of the extension above - CharMinusOne - is of type Char - "ByVal C As Char" - so that's the type being extended here.

The hard part is (well ... mostly) over now because consuming extensions is simple. One of the real achievements of the Visual Basic developers was to make extensions fully incorporated into Intellisense just as soon as they're coded and in scope for the consuming code. That means that if the AVBStringNS is in scope, all we have to do is start coding ...

--------
Click Here to display the illustration
Click the Back button on your browser to return
--------

On the next page, I put this extension to use.

Explore Visual Basic
By Category
About.com Special Features

The Best Web Trends of the Decade

A look back at the best innovations, ideas and technologies over the last 10 years, More >

Family Tech Center

Stay connected and entertained with reviews on tips on the latest HDTVs, cellphones and more. More >

  1. Home
  2. Computing & Technology
  3. Visual Basic
  4. Using VB.NET
  5. Extension Methods in VB.NET

©2010 About.com, a part of The New York Times Company.

All rights reserved.