So Monday (11/19/07) marked the RTM of Visual Studio 2008 and Framework 3.5. There's so many new features. I already feel way behind.

I started playing with some of the language enhancements to Visual Basic 9. My aren't we growing up! All object-oriented languages have some similarities to some degree, but Microsoft has been taking leaps forward into making its OO languages more robust with each version of the framework.

The first that I had to sit down and code something for myself to grasp is the concept of method extensions. We all understand how to extend a class by inheritance. Well, what if the class is marked NotInheritable? What if you don't have access to the code of the NotInheritable class?

When I first heard about this, I was baffled as to how that made any sense. If I marked my class NotInheritable, then I would hope that noone could ever extend that class. With all of the other code using my class, why would I want someone to have the ability to inherit from it to change the contract and potentially break other code?

Let's look at adding an extension method to the NotInheritable class System.String. Suppose we want to add a method to String to return alternating case combining ToUpper() and ToLower(). There are a couple rules that we find. An extension method must be defined as Public within a Module (VB) or Static Class (C#). It also must have the <Extension()> attribute, and can only be a function or subroutine (no properties, etc.)
Imports System.Text

Imports System.Runtime.CompilerServices

Module Extensions

<Extension()> _
Public Function ToAlternatingCase(ByVal s _
As String) As String
Dim upper = True
Dim result = New StringBuilder()
For i = 0 To s.Length - 1 Step 1
If upper Then
result.Append(s(i).ToString() _
.ToUpper())
Else
result.Append(s(i).ToString() _
.ToLower())
End If
upper = Not upper
Next
Return result.ToString()
End Function

End Module
Now, in our Main method:

Module MainModule


Sub Main()
Dim s = "hello world"
Console.WriteLine(s.ToAlternatingCase())
End Sub

End Module
The extension method is automatically wired for the String class since we passed a String class as a parameter in. Yes, it's already there in Intellisense!

You may have also noticed the usage here of type inference. That is declaring without explicitly defining the type (I.E. "As String"). This is yet another new enhancement and a whole other subject for another time. I'm yet to be convinced what benefit we see from that other than less code to write, and it seems to open the door for more bugs from the more junior devs on the team.

Back to extensions... Suppose you want to override a method with an extension method. That's where I immediately thought problems would occur. The compiler will automatically ignore the extension and call the instance method. Intellisense doesn't even show the extension available to the class. Whew!

You can however overload an instance method with an extension method! :
    <Extension()> _

Public Function ToString(ByVal s As String, _
ByVal x As String) As String
Return s.ToString() & x.ToString()
End Function
    Sub Main()

Dim s = "hello world"
Console.WriteLine(s.ToAlternatingText() _
.ToString("!"))
End Sub
    Result : HeLlO WoRlD!
Again the first parameter is to define the type that the method extends, and each additional parameter provides the overload.

One last note that I've seen is that extensions cost nothing more than calling any other shared method in case anyone wondered about performance hits.

Very interesting stuff. I look forward to seeing this used in actual production code and to exploring the many other new enhancements to the languages.