CSharp/C# Tutorial - C# Extension Methods






Extension methods can extend an existing type with new methods without altering the definition of the original type.

An extension method is a static method of a static class, where the this modifier is applied to the first parameter.

The type of the first parameter will be the type that is extended.

For example:


public static class StringExtension {
   public static bool IsCapitalized (this string s) {
      if (string.IsNullOrEmpty(s))
         return false;
      return char.IsUpper (s[0]);
   }
}

The IsCapitalized extension method can be called as though it were an instance method on a string, as follows:


Console.WriteLine ("Javascript".IsCapitalized());

An extension method call is translated back into an ordinary static method call:


Console.WriteLine (StringExtension.IsCapitalized ("Javascript"));

Interfaces can be extended too:


public static T First<T> (this IEnumerable<T> sequence){
    foreach (T element in sequence)
        return element;
    throw new InvalidOperationException ("No elements!");
}
...
Console.WriteLine ("Javascript".First()); // J





Extension methods versus instance methods

Any compatible instance method takes precedence over an extension method.

In the following example, Main's MyMethod method will always take precedence -even when called with an argument x of type int:


class Main {
   public void MyMethod (object x) { } 
}

static class Extensions {
   public static void MyMethod (this Main t, int x) { }
}

The only way to call the extension method in this case is via normal static syntax:


Extensions.MyMethod(...)




Extension methods versus extension methods

If two extension methods have the same signature, the extension method must be called as an ordinary static method to disambiguate the method to call.

If one extension method has more specific arguments, the more specific method takes precedence.

The following code shows how to use it:


static class StringExtension {
    public static bool IsCapitalized (this string s) {...}
}
static class ObjectHelper {
    public static bool IsCapitalized (this object s) {...}
}

The following code calls StringExtension's IsCapitalized method:


bool test1 = "Javascript".IsCapitalized();

To call ObjectHelper's IsCapitalized method, we must specify it explicitly:


bool test2 = (ObjectHelper.IsCapitalized ("Javascript"));

Classes and structs are considered more specific than interfaces.