Saturday, April 14, 2012

Extension Methods in .NET

Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type. For client code written in C# and Visual Basic, there is no apparent difference between calling an extension method and the methods that are actually defined in a type.

Binding Extension Methods at Compile Time
You can use extension methods to extend a class or interface, but not to override them. An extension method with the same name and signature as an interface or class method will never be called. At compile time, extension methods always have lower priority than instance methods defined in the type itself.
With traditional object-oriented development, extending classes is typically achieved by deriving from a base class and enhancing the functionality in the derived class. Visual Basic® still supports these object-oriented concepts, but classes are sometimes marked NotInheritable to prevent modification of their behavior through inheritance. As a result, there is no way to customize these classes. An example of this is the System.String class.
A new feature made available in Visual Basic 2008, however, lets you extend any existing type's functionality, even when a type is not inheritable. And these extension methods play a crucial role in the implementation of LINQ.

Extension methods provide a simple mechanism to extend types in the system (value, reference, and interface types) with new methods. These methods extend the original type and can be called like regular, defined instance methods, but they leave the original type and its methods untouched. Extension methods create the illusion that they are defined on a real type, but, in reality, no changes are made to the original types.

Performance

Performance is relatively unaffected. Even though your Visual Basic source code may look different, it compiles to a simple shared method call and generates the same IL as if you had used the shared method call. So there is no performance hit through using them.

 
extension methods are not a replacement for object-oriented concepts. If you are familiar with object-oriented concepts and have a well-designed application, you are probably already using inheritance somewhere in your application and should continue doing so. You probably own many of the types you are using, meaning you have access to the source code and can extend the functionality through normal object-oriented concepts. Extension methods really provide a way to enhance classes that you previously could not extend. Extension methods should be used sparingly, when other approaches are not possible or suitable.



Writing Extension Methods:
The basic outline of creating an extension methods goes something like this:
  1. Create a public static class (module in VB) 
  2. Define functions
  3. Make the functions an extension method

1. Create a public static class (module in VB) 
// C#
public static class MyExtensions
{
}

' VB
Module MyExtensions        
End Module

2. Define functions
// C#
public static class MyExtensions
{
     public string GetFirstCharacter(String str)
    {
        if(str.Length < 1)
        {
            return str;
        }
        else
        {
            return str.Substring(0,1);
        }
    }
}


' VB
Module MyExtensions

Public Function GetFirstCharacter(Byval str As String) As String
    If (str.Length < 1) Then
        return str
    Else
        return str.SubString(0,1)
    End If
End Function

End Module

                               
3. Make the functions an extension method
To make our C# version of our function, we need an extension method to mark the function as static (so that it can be accessed at any time without the need for declaring anything) and secondly, mark the first parameter with the this keyword. This keyword basically tells the CLR that when this extension method is called, to use "this" parameter as the source. See the following:
// C#
public static class MyExtensions
{
     public static string GetFirstCharacter(this String str)
    {
        if(str.Length < 1)
        {
            return str;
        }
        else
        {
            return str.Substring(0,1);
        }
    }
}

Now for the VB version. Instead of using the this keyword, we need to do something slightly different. We need to mark the function with the System.Runtime.CompilerServices.Extension attribute like so

<System.Runtime.CompilerServices.Extension> _
Public Function GetFirstCharacter(Byval str As String) As String
    If (str.Length < 1) Then
        return str
    Else
        return str.SubString(0,1)
    End If
End Function

Now you can use this method in your project  as follows
// C#
String str = "Hello";
str = str.GetFirstCharacter();

' VB
Dim str as String = " Hello"
str = str. GetFirstCharacter ()


Please let me know if it helps or if you have any queries...
References :
http://msdn.microsoft.com/en-us/library/bb383977.aspx
http://msdn.microsoft.com/en-us/magazine/cc163317.aspx