Extension Methods in C#


Extension methods make it possible to write a method to a class that doesn't offer the method at first. You can also add a method to any class that implements a specific interface, so multiple class can make use of the same implementation.

For example , wouldn't you like to have a ExtStr() method with the String class? The string class is sealed, so it is not possible to inherit from this class. You can do an extension method , as given :

public static class StringExtension
{
    public static void ExtStr(this string str)
    {
        Console.WriteLine(ExtStr invoked for {0}, str);
    }
}

An extension method is declared in a static class. An extension method is defined as static method where the first parameter defines the type it extends. The ExtStr() method extends the string class, as is defined with the first parameter. For differentiating extension methods from normal static methods, the extension method also requires the this keyword with the first parameter. Indeed, it is now possible to use the ExtStr() with the string type:

string str="Hi";
str.ExtStr();

The result shows ExtStr invoked for Hi in the console, because HI is the string passed to the ExtStr() method.

This might appear to be breaking object -" oriented rules because a new method is defined for a type without changing the type. However, this is not the case. The extension method cannot access private members of the type it extends. Calling an extension method is just a new syntax of invoking a static method. With the string you can get same result by calling the method ExtStr() this way:

string str="Hi";

StringExtension.ExtStr(str);

To invoke the static method, write the class name followed by the method name. Extension methods are a different way to invoke static methods. You don't have to supply the name of the class where the static method is defined. Instead, the static method is taken because of the parameter type. You just have to import the namespace that contains the class to get the ---- extension method in the scope of the String class.

One of the classes that define LINQ extension methods is Enumerable in the namespace System.Linq. You just have to import the namespace to open the scope of the extension methods of this class. A sample implementation of the Where() extension method is shown here. The first parameter of the Where() method that includes the this keyword is of type IEnumerable<T>. This way the Where() method can be used with every type that implements IEnumerable<T>. To mention just a few examples, arrays and List<T> implement Inumerable<T>. The second parameter is a Func<T,bool> delegate that references a method that returns a Boolean value and requires a parameter of type T. This predicate is invoked within the implementation to examine if the item from the IEnumerable<T> source should go into the destination collection. If the method is referenced by the delegate, the yield return statement returns the item from the source to the destination.

 public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source,Func<TSource, bool> predicate)
    {
        foreach (TSource item in source)
            if (predicate(item))
                yield return item;
    }

Because Where() is implemented as a generic method, it works with any type that is contained in a collection. Any collection implementing IEnumerable<T> is supported.

Note: The extension methods are defined in the namespace System.Linq in the assembly System.Core

Now it's possible to use the extension method Where(), OrderByDescending(), and Select() from the class Enumerable. Because each of these methods returns IEnumerable<TSource>, it is possible to invoke one method after the other by using the previous result. With the arguments of the extension methods, anonymous methods that defined the implementation for the delegate parameters are used.

 private static void ExtensionMethods()
{
    List < Champ > champions =
    new List < User > (
    Formula1.GetUserions());
    IEnumerable < Champ  > IndiaChampions =
    champions.Where(
    delegate(Champ  r)
    {
    return r.Country == "India;
    }).OrderByDescending(
    delegate(Champ  r)
    {
    return r.Wins;
    }).Select(
    delegate(Champ  r)
    {
    return r;
    });
    foreach (Champ  r in IndiaChampions)
    {
    Console.WriteLine({0:A}, r);
    }
}