User Tools

Site Tools


notes:csharp:extensionmethods

Extension Methods in C#

An extension method is a static method of a static class. You can use it to extend functionality of a class, a struct, or an interface. The first parameter of an extension method is the type that is being extended preceded by the this keyword.

Remember that the difference between a regular static method and an extension method is the this keyword for the first argument.

Extension methods vs. instance methods:

  • Any compatible instance method always takes precedence over an extension method. The only way to call the extension method in this case is via static syntax.
  • 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.

Example: Extend the String type:

public static class StringHelper
{
    public static bool StartsWithDigit(this string s)
    {
        if (String.IsNullOrEmpty(s))
            return false;
        else
            return Char.IsDigit(s[0]);
    }
}
...
bool b1 = "7 Monkeys".StartsWithDigit();    // true
bool b2 = "Seven Dwarfs".StartsWithDigit(); // false
...
bool b1 = StringHelper.StartsWithDigit("7 Monkeys");    // true
bool b2 = StringHelper.StartsWithDigit("Seven Dwarfs"); // false

Example: Extend a custom type Customer:

// A custom type we are extending.
public class Customer
{
    private int id; 
 
    public string Message { get; set; }
    public void ArchiveMessages();
    // ...
}
 
// An extension method.
public static class CustomerExtension
{
    public static void SendMessage(this Customer cust, string message)
    {
        // You have access to the public properties and methods of the type being extended
        // but you don't have access to the private members.
        cust.Message = message;
        cust.ArchiveMessages();
        // ...
    }
}
...
Customer cust = new Customer();
cust.SendMessage("Hello Burak"); // use the extension method

Example: Extend an interface IEnumerable<T>:

Adding an extension method on an interface propagates the method to all classes that implement this interface.

public static class EnumerableExtension
{
    public static T First<T>(this IEnumerable<T> sequence)
    {
        foreach (T element in sequence)
            return element;
 
        throw new InvalidOperationException("Empty collection");
    }
 
    public static IEnumerable<T> Where<T>(this IEnumerable<T> sequence, Func<T, bool> predicate)
    {
        foreach (T element in sequence)
        {
            if (predicate(element)) yield return element;
        }
    }
}
...
List<int> list = new List<int> { 8, 3, 4, 7, 5 };
 
int first = list.First(); // 8
 
var odd = list.Where(i => i % 2 != 0); // 3,7,5
 
// Extension methods can be chained.
int firstOdd1 = list.Where(i => i % 2 != 0).First(); // 3
 
// The same but using static methods.
int firstOdd2 = 
    EnumerableExtension.First(EnumerableExtension.Where(list, i => i % 2 != 0)); // 3

References

notes/csharp/extensionmethods.txt · Last modified: 2016/11/28 by admin