Friday, August 24, 2007 12:00 AM
bart
Visual Basic 9.0 Feature Focus - Extension Methods
Welcome back to the Visual Basic 9.0 Feature Focus blog series. In this post, we'll cover Extension Methods, a feature also available in C# 3.0 (see here). Extension methods allow you to "extend" an existing type with an instance method, at least virtually. That is, in reality an extension method is a Module's Shared method or function, but which can be called with instance method call syntax. Consider the following problem in VB 8.0:
Dim s As String = "Bart De Smet"
Dim t = s.ToLower().Reverse().Substring(0, 4)
The problem in the fragment above is the lack of a Reverse instance method on System.String. A possible solution is to write a helper method like this:
Module MyExtensions
Function Reverse(ByVal s As String) As String
Dim c As Char() = s.ToCharArray()
Array.Reverse(c)
Return New String(c)
End Function
End Module
which can be called like this:
Dim s As String = "Bart De Smet"
Dim t = MyExtensions.Reverse(s.ToLower()).Substring(0, 4)
This is quite counterintuitive because the Reverse call is moved to the front of the method call chain. Because System.String is sealed and you typically don't have the code available for 3rd party libraries to put the extension in there, you're restricted to a shared function. However, in VB 9.0 you can declare the method as an extension method, like this:
Imports System.Runtime.CompilerServices
Module MyExtensions
<Extension()> _
Function Reverse(ByVal s As String) As String
Dim c As Char() = s.ToCharArray()
Array.Reverse(c)
Return New String(c)
End Function
End Module
Now you can write the following:
Dim s As String = "Bart De Smet"
Dim t = s.ToLower().Reverse().Substring(0, 4)
Internally, this gets translated into this (as in our manual VB 8.0 code fragment):
Dim s As String = "Bart De Smet"
Dim t = MyExtensions.Reverse(s.ToLower()).Substring(0, 4)
Notice that the method shows up in the IntelliSense method list and is marked as an <Extension> together with a slightly different icon (the blue arrow indicates the method is an extension).
Extensions are brought in scope by means of namespaces. Assume the extensions module is defined in a namespace, like this:
Imports System.Runtime.CompilerServices
Namespace Sample
Module MyExtensions
<Extension()> _
Function Reverse(ByVal s As String) As String
Dim c As Char() = s.ToCharArray()
Array.Reverse(c)
Return New String(c)
End Function
End Module
End Namespace
then you can bring the Reverse extension method in scope by writing the following:
Imports Sample
Extension methods can be either a Sub or a Function and have at least one parameter, which is the one that becomes the left-hand side of the instance method invocation syntax:
You can add as many parameters you want after the special-treated first parameter; these become the "real parameters" used when calling the method using instance method invocation syntax:
Module MyExtensions
<Extension()> _
Sub Bar(ByVal s As String, ByVal a As Integer, ByVal b As Integer, ByVal c As Integer) As String
End Sub
End Module
can be called like this:
Dim s As String = "Bart De Smet"
s.Bar(1, 2, 3) 'equivalent to calling MyExtensions.Bar(s, 1, 2, 3)
Extension methods can be defined on classes, structures and interfaces and can use most parameter list features that Visual Basic offers, except for an Optional or ParamArrays first parameter. Also, make sure your extension methods are CLS compliant so that these can be used from other languages too (like C# 3.0).
Happy coding!
Del.icio.us |
Digg It |
Technorati |
Blinklist |
Furl |
reddit |
DotNetKicks
Filed under: VB 9.0