Understanding Extension Methods
•        As you know, once a type is defined and compiled into a .NET assembly, its definition is, more or less,
final.
•        The only way to add new members, update members or remove members is to recode and recompile the
code base into an updated assembly…
•        … or take more drastic measures, such as using the System.Reflection.Emit namespace to dynamically
reshape a compiled type.
•        Extension methods allow you extend the functionality of previously compiled types.
•        Using extension methods, you can add functionality to precompiled types, while providing the illusion
these methods were there all along.
•        This technique can be quite helpful when you need to inject new functionality into types for which you
do not have an existing code base.
•        It can also be quite helpful when you need to force a type to support a set of members (for the interest of
polymorphism) but cannot modify the original type declaration.
•        As well, LINQ technologies make use of extension methods to integrate query expression support into the
.NET base class libraries.
•        In C#, extension methods can only be defined within a static class.
•        All extension methods are marked as such by using the this keyword as a modifier on the first (and only
the first) parameter of the method in question.
•        This parameter represents the data type being extended.
•        Once implemented, extension methods can either be called from the correct instance in memory, or
statically via the defining static class.

•        In VB, extension methods must be marked with the <Extension> attribute.
•        This type is defined within the System.Runtime.CompilerServices namespace.
•        As well, VB extension methods can only be defined in Module types (not Class or Structure types).
•        Assume you are authoring a utility type named MyExtensions that defines an extension method.
•        The method allows any object in the .NET base class libraries to have a brand new method named
DisplayDefiningAssembly().
// C#
using System.Reflection;

static class MyExtensions
{
// This method allows any object to display the assembly
// it is defined in.
public static void DisplayDefiningAssembly(this object obj)
{
Console.WriteLine("{0} lives here: {1}", obj.GetType().Name,
Assembly.GetAssembly(obj.GetType()));
}
}

' VB
Imports System.Runtime.CompilerServices
Imports System.Reflection

Public Module MyExtensions
<Extension()> _
Sub DisplayDefiningAssembly(ByVal obj As Object)
Console.WriteLine("{0} lives here: {1}", obj.GetType().Name, _
Assembly.GetAssembly(obj.GetType()))
End Sub
End Module

•        Understand of course that a given extension method could have multiple parameters, however the first
parameter always denotes the item being extended.
•        To illustrate, here is an overloaded extension method.
// C#
static class MyExtensions
{
...
// Every Int32 now has a Foo() method...
public static void Foo(this int i)
{ Console.WriteLine("{0} called the Foo() method.", i); }

// ...which has been overloaded to take a string!
public static void Foo(this int i, string msg)
{ Console.WriteLine("{0} called Foo() and told me: {1}", i, msg); }
}

' VB
Module MyExtensions
...
' Every Int32 now has a Foo() method...
<Extension()> Public Sub Foo(ByVal i As Integer)
Console.WriteLine("{0} called the Foo() method.", i)
End Sub

' ...which has been overloaded to take a string!
<Extension()> Public Sub Foo(ByVal i As Integer, ByVal msg As String)
Console.WriteLine("{0} called Foo() and told me: {1}", i, msg)
End Sub
End Module

•        Now consider the following usage:
•        The VB code differs only by the declaration of the variables (via the Dim keyword) and removal of semi-
colons.
//C#
static void Main(string[] args)
{
Console.WriteLine("***** Fun with Extension Methods *****\n");

// The int has assumed a new identity!
int myInt = 12345678;
myInt.DisplayDefiningAssembly();

// So has the DataSet!
System.Data.DataSet ds = new System.Data.DataSet();
ds.DisplayDefiningAssembly();

// And the SoundPlayer!
System.Media.SoundPlayer sp = new System.Media.SoundPlayer();
sp.DisplayDefiningAssembly();

// Use new integer functionality.  
myInt.Foo();
myInt.Foo("Ints that Foo?  Who would have thought it!");

// This would be an error!  Booleans don’t have the Foo() method!
bool b2 = true;
b2.Foo();
}



•        It is also possible to apply extend an interface type with new members, however:
•        The extension method provides an implementation of the new interface method.
•        This should make sense, as it is illegal to define abstract static members.
// C#
namespace ExtensionInterface
{
// Define a CLR interface in C#.
interface IMyInterface
{
void MethodOne();
}

// Implementation of IMyInterface.
class Test : IMyInterface
{    
public void MethodOne()
{
Console.WriteLine("MethodOne called");
}
}

static class Extensions
{
// Extend IMyInterface with a second method,
// and provide an implementation.
public static void MethodTwo(this IMyInterface itf)
{
Console.WriteLine("MethodTwo called");
}
}

class Program
{
static void Main(string[] args)
{
// Test now has two methods!
Test c = new Test();
c.MethodOne();
c.MethodTwo();
}
}
}

•        The VB code is as you would expect:
Imports System.Runtime.CompilerServices

' Define a CLR interface in VB.
Interface IMyInterface
Sub MethodOne()
End Interface

' Implementation of IMyInterface.
Class Test
Implements IMyInterface
Public Sub MethodOne() Implements IMyInterface.MethodOne
Console.WriteLine("MethodOne called")
End Sub
End Class

Module Extensions
' Extend IMyInterface with a second method,
' and provide an implementation.
<Extension()> _
Public Sub MethodTwo(ByVal itf As IMyInterface)
Console.WriteLine("MethodTwo called")
End Sub
End Module

Module Program
Sub Main()
' Test now has two methods!
Dim c = New Test()
c.MethodOne()
c.MethodTwo()
End Sub
End Module

•        When you are defining extension methods in C#, be aware that types in other namespaces do not have
direct access.
•        In C#, you are required to import the correct namespace defining your static extension class.
•        In VB, this is not required as Module types simulate a ‘global’ namespace.
•        However, if your extension methods are defined within a *.dll, you will need to reference the assembly
(and use the namespace) accordingly.
•        Finally, be aware that in Visual Studio, IntelliSense will show you which members are extension methods.
•        Look for the icon with a blue downward arrow.
•        Notice in the following screen shot, DisplayDefiningAssembly() and Foo() have the new extension
method icon.
Copyright (c) 2008.  Intertech, Inc. All Rights Reserved.  This information is to be used exclusively as an
online learning aid.  Any attempts to copy, reproduce, or use for training is strictly prohibited.
Extension Methods
Copyright (c) 2008.  Intertech, Inc. All Rights Reserved.  This information is to be used exclusively as an
Table of Contents
Courseware
Training Resources
Tutorials