text: Extension Methods (Visual Basic)
  Visual Basic 2008 introduces extension methods, which enable developers to add custom functionality to data types that are already defined without creating a new derived type. Extension methods make it possible to write a method that can be called as if it were an instance method of the existing type.
  An extension method can be only a Sub procedure or a Function procedure. You cannot define an extension property, field, or event. All extension methods must be marked with the extension attribute <Extension()> from the System.Runtime.CompilerServices namespace.
  The first parameter in an extension method definition specifies which data type the method extends. When the method is run, the first parameter is bound to the instance of the data type that invokes the method.
  Description
  The following example defines a Print extension to the String data type. The method uses Console.WriteLine to display a string. The parameter of the Print method, aString, establishes that the method extends the String class. Print is in scope, the method can be called as if it were an ordinary instance method that takes no arguments, such as ToUpper:.
  The method is called by sending in a string argument for punc: example.PrintAndPunctuate(".")
  The following example shows Print and PrintAndPunctuate defined and called. System.Runtime.CompilerServices is imported in the definition module in order to enable access to the extension attribute.
  Code
  Imports System.Runtime.CompilerServices Module StringExtensions <Extension()> _ Public Sub Print(ByVal aString As String) Console.WriteLine(aString) End Sub <Extension()> _ Public Sub PrintAndPunctuate(ByVal aString As String, _ ByVal punc As String) Console.WriteLine(aString & punc) End Sub End Module
  Next, the extension methods are brought into scope and called..
  The first call to ExampleMethod in the following code calls the extension method, because arg1 is Long and is compatible only with the Long parameter in the extension method. The second call to ExampleMethod has an Integer argument, arg2, and it calls the instance method.
  Now reverse the data types of the parameters in the two methods:
  This time the code in Main calls the instance method both times. This is because both arg1 and arg2 have a widening conversion to Long, and the instance method takes precedence over the extension method in both cases.
  Therefore, an extension method cannot replace an existing instance method. However, when an extension method has the same name as an instance method but the signatures do not conflict, both methods are can be accessed. For example, if class ExampleClass contains a method named ExampleMethod that takes no arguments, extension methods with the same name but different signatures are permitted, as shown in the following code.
  Imports ConsoleApplication2.ExtensionExample Module Module End Module
  The output from this code is as follows:
  Extension method
  Instance method
  The situation is simpler with properties: if an extension method has the same name as a property of the class it extends, the extension method is not visible and cannot be accessed. Print method in the earlier example is defined in a module named StringExtensions, the fully qualified name is StringExtensions.Print(example) instead of example.Print().