I have only just recently had the time to play with the new features available in VS 2008 and one of the first things that I thought I would take a look at were Extension Methods.
In a nutshell, extension methods allow you to attach a method onto any .NET type and utilise that method as if it was part of the type out of the box. If you consider the String type, there are many methods attached to the String type that allow you to retrieve it's length, convert the string to upper or lower case, determine if it contains a specific value and so on. However, as with most things in life, there is always something missing. For example, it would be nice if we could proper case the string or determine if the string contained a valid value such as an email address. In the past, this type of functionality would be left to a helper class that we as developers would create ourselves.
However, with the introduction of extension methods, we can now turn our helper class methods into extension methods of the necessary type and use those methods in the same way that we would any method of the native .NET type.
To create an extension method in VB 9 we must use a Module as all extension methods must be shared, also the method must be decorated with the Extension attribute. So taking the two examples above (proper casing a string and determining if a string is a valid email address format) we might create a module called "StringExtensions" as follows:
Option Strict On
Imports System.Runtime.CompilerServices
Namespace MyExtensions
Module StringExtensions
_
Public Function ToProperCase(ByVal s As String) As String
Dim titleCase As System.Globalization.TextInfo = New System.Globalization.CultureInfo("en-GB", False).TextInfo Return titleCase.ToTitleCase(s)
End Function
_
Public Function IsValidEmailAddress(ByVal s As String) As Boolean
Dim regEx As New System.Text.RegularExpressions.Regex( _
"^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$", _ Text.RegularExpressions.RegexOptions.IgnoreCase)
Return regEx.IsMatch(s)
End Function
End Module
End Namespace
Note that in the two method examples above, the first argument (and only argument in these examples) is of type string, this is because the first argument of any extension method must be of the type that you are extending.
Now that we have this extension method module, all that we need to do in order to utilise it is import the necessary namespace into our declaring code and utilise the new methods:
Option Strict On
Imports ConsoleApplication1.MyExtensions.StringExtensions
Module Module1
Sub Main()
'Output a proper case string
Console.WriteLine("joe bloggs".ToProperCase)
'Test for valid email address
Console.WriteLine("joe.bloggs@somedomain.com".IsValidEmailAddress.ToString) 'Returns True Console.WriteLine("joe.bloggs-somedomain.com".IsValidEmailAddress.ToString) 'Returns False
Console.ReadLine()
End Sub
End Module
Note also that these extension methods appear in Intellisense just as any other method of a type would, which makes this easier for developers of a team to discover new type methods:
Another area where I think extension methods will prove extremely useful is when wishing to extend a custom class without creating a new version or inheriting from an existing version in order to add extra functionality.