What is Extension Methods

Nakul.Lande
Posted by in .NET Framework category on for Intermediate level | Points: 250 | Views : 10060 red flag

Extension Methods were first introduced in VB.NET 2008 primarily to support LINQ - Language Integrated Query. But they open up a whole new dimension of programming possibilities by themselves. In this article we will take a look how these extension methods help new age of developer to extend the DLLs and Exes with new functionality like cherry on top

As

1. Introduction :

As we know and learned in OOPs that once a Class 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 you could take more drastic measures such as using the System.Reflection.Emit namespace to reshape a compiled type dynamically. System.Reflection gives you some overview of a class and but won’t help to add anything new in class.

2.  Objective :

So what is Extension Method?

Extension methods allow existing classes to be extended without relying on inheritance or having to change the class's source code. This means that if you want to add some methods into the existing String class you can do it quite easily. Extension method is a special kind of static method but they are called using instance method syntax. Their first parameter specifies which type the method operates on, and the parameter is preceded by “this” modifier.
                         
When you create extension methods, the existing precompiled assembly is not literally modified. Rather, the class type is extended within the current project. If you package extension methods into a custom .NET *.dll, other applications would need to reference this library to make use of the extensions. To this end, extension methods are really just a way to ‘pretend’ a type has new functionality. The real type is not modified in any way.

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. Extension Methods were first introduced in VB.NET 2008 primarily to support LINQ - Language Integrated Query. But they open up a whole new dimension of programming possibilities by themselves.

Here's a definition for Extension Methods from VB Compiler Team:

"Extension methods enable you to create a method in a module decorated with an attribute and have that method appear as if it was an instance method defined on another type."

How to declare Extension Method?
In C#, extension methods can only be defined within a static class. All extension methods are marked as such by using ‘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.

public static class MyProgram

{

  public static int WordCount(this String aString)

  {

   return    aString.Length;

  }

}

In VB, the extension method definition is marked with the extension attribute <Extension()>. Marking the module in which the method is defined is optional, but each extension method must be marked. 

System.Runtime.CompilerServices must be imported in order to access the extension attribute.

Imports System.Runtime.CompilerServices  '' To access Extension method

Module MyModule

    '' Define the Extension method in Module

    <Extension()>

    Public Function WordCount(ByVal aString As String) As Int16

        Return aString.Length

    End Function

End Module

Once implemented, extension method can be called from class instance just like other public instance methods of a class.

C#.Net

String str = “ABCDEFG”;

 int i = str. WordCount();

 

VB.Net

Dim str As String = "ABCDEF"

Dim i As Int16 = str.WordCount()

Even though Extension methods are powerful technique to extend functionality, but there are some thumb rules regarding do’s and Don’ts for Extension methods.

Do’s:

  • Use Extension methods when you don't control the types (class) being extended for new functionality.
  • Use Extension methods where you don't want to force the original implementer of class to provide code that can be easily done using the existing methods.

Don’t:

  • Extension methods cannot be used to override existing methods.
  • An extension method with the same name and signature as an instance method will not be called.
  • The concept of extension methods cannot be applied to fields, properties or events.
  • When polymorphism is critical; you cannot guarantee that your code will be the version that gets executed with an extension method, as the original methods of a class takes precedence.
  • When you need access to private/protected members

Another universal truth that we have to keep in mind while writing Extension method is that the instance method (original class method) has higher precedence over Extension method even if the extension method is a better match.

Let’s take a look of following example to understand how instance method precedence over Extension Method.  In the example given below both arg1 and arg2 have a widening conversion to Long, the instance method takes precedence over the extension method in both cases.

Imports System.Runtime.CompilerServices  '' To access Extension method
Module MyModule

    Public Class ExampleClass
        Public Sub Method(ByVal m As Long)
            ' This is an instance method taking Long input parameter
            Console.WriteLine("Instance method with Long input parameter.")
        End Sub
    End Class

    <Extension()>
    Sub Method(ByVal ec As ExampleClass, ByVal n As Integer)
        ' This is an extension method for ExampleClass taking Integer input parameter
        Console.WriteLine("Extension method taking Integer input parameter.")
    End Sub

    Public Sub main()

        Dim arg1 As Long = 10
        Dim arg2 As Integer = 5

        '' create instance of ExampleClass
        Dim obj As New ExampleClass()
        obj.Method(arg1) '' Pass Long parameter
        obj.Method(arg2) '' Pass Int parameter

        System.Console.Read()
    End Sub
End Module

Output:


The extended methods which don’t take extra parameter (other than class type) can be access as Extended method of type as well as static method. In the following example
we have added as extended method “Reverse()” in string class. This method takes only type parameter while declaration (i.e.,
this string strReverse). This method can be access as instance method of String class as well as static method of myExtensionClass class.

 

namespace MyExtensionExample
{
    public static class myExtensionClass
    {
        // static class used to write Extension method
        public static string Reverse(this string strReverse)
        {
            char[] charArray = new char[strReverse.Length];
            int len = strReverse.Length - 1;
            for (int i = 0; i <= len; i++)
            {
                charArray[i] = strReverse[len - i];
            }
            return new string(charArray);
        }
        
    }


    public class Program
    {
        static void Main(string[] args)
        {
            string str = "ABCDEFG";
            
            // Call the extension method 'Reverse' as instance method of String class
            System.Console.WriteLine("Extension method 'Reverse' as instance method of String class : Output-> " + str.Reverse());

            // Call the extension method as Static method of static class
            System.Console.WriteLine("Extension method as Static method of static class : Output-> " + myExtensionClass.Reverse(str));     
                          
        }
    }
}

Output : 


3.  Some Frequently used Extension Methods in LINQ :

a. StartsWith: “StartsWith” extension method is used to retrieve all records from the collection whose particular field starts with certain characters or string.

 

// select all records whose name starts with "Bob"

var query1 = from sample in list

where sample.name.StartsWith("Bob")

select sample;

 

b. Average: “Average” extension method is used to get the average of a particular column from the collection objects. In given example, I want to get the average of AutoId, so it is specified using lambda expressions (=>).

// gets the average of the specified column

var average = query1.Average(s => s.AutoId);

 

c. Contains: “Contains” extension method is used to retrieve all objects from the collection whose field contains specified string.

 

// select all records whose name contains "Bob"

var query1 = from sample in list

where sample.name.Contains("Bob")

select sample;

 

           d. Distinct: Distinct” extension method is used to get the distinct records from the collection (similar to sql server distinct keyword).

// Distinct - gives distinct record

var distinctRecords = queryConcat.Distinct();

 

e. ElementAt: ElementAt” extension method is used to get the element (object) from the specified position in the collection. The following example specified 3 so this will give me the element at the 4th position (as it uses 0 based index).

In case the position you have specified doesn't exists in the collection, it throws error. To avoid error use ElementAtOrDefault method.

//ElementAt - gives the record that is at nth position in the collection, if nth position doesn't exists then throw error

var samp = query1.ElementAt(3);

f. ElementAtOrDefault: ElementAtOrDefault” extension method is used to retrieve the specified position element from the collection and if specified position doesn't exist then it returns null.

// ElementAtOrDefault - gives the record that is at nth position in the collection if not found then returns null

var samp1 = query1.ElementAtOrDefault(4);

g. Except: Except” extension method is used to retrieve all records from the collection that doesn't have in the second collection.

// Except - Get the list of collection that doesn't contain records from specified collection

var exceptColl = query1.Except(query2);

There are many more extension methods those are frequently used in LINQ and you will get it on MSDN website. I don’t want to mention all these Extension Methods here as this article roams around an idea of Extension method and to specifics to LINQ extension methods.

4. Conclusion :

Before extension methods were created, you could not call your own method on an instance of an object that you could not add an implementation to (e.g. interface because they cannot have implementations or library classes because they are already compiled). Extension methods fill this gap by allowing you to make methods that appear to be callable on instances of objects, while being defined externally to the implementation of the object.

This keyword has to be the first parameter in the extension method parameter list.

 

Extension methods are used extensively in C# 3.0 and further version specially for LINQ extensions in C#, for example:

    

int[] ints = { 10, 45, 15, 39, 21, 26 };

var result = ints.OrderBy(g => g);

Here, OrderBy is a sample for extension method from an instance of IEnumarable<T> interface, the expression inside the parenthesis is a lambda expression.

It is important to note that extension methods can't access the private methods in the extended type.

 

If you want to add new methods to a type, you don't have the source code for it, the ideal solution is to use and implement extension methods of that type.

 

If you create extension methods that have the same signature methods inside the type you are extending, then the extension methods will never be called.

5.  References :

Page copy protected against web site content infringement by Copyscape

About the Author

Nakul.Lande
Full Name: Nakul Lande
Member Level: Bronze
Member Status: Member
Member Since: 7/24/2012 5:13:29 PM
Country: United States
Nakul Lande
http://www.dotnetfunda.com

Login to vote for this post.

Comments or Responses

Login to post response

Comment using Facebook(Author doesn't get notification)