BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

C# Programming
.NET 3.5+

C# Extension Methods

Sometimes it is necessary to add functionality to a library for which you do not own the source code and where using inheritance to subclass functionality is not viable. This problem can be overcome with the careful use of C# 3.0 extension methods.

Adding Parameters

Extension methods may include parameters as with any other type of method. The parameters that will be used in the calls to the method must be added after the argument that is decorated with the "this" keyword. To demonstrate, we can modify our method to accept two parameters. These will be outputted to the console as a prefix and a suffix.

public static void OutputToConsole(this string s, string prefix, string suffix)
{
    Console.WriteLine("{0}{1}{2}", prefix, s, suffix);
}

To test the modified extension method, update the Main method of the program:

string testString = "Hello, world.";
testString.OutputToConsole("[", "]");   // Outputs "[Hello, world.]"

Extension Methods and Inheritance

When an extension method is applied to a base class, all of its subclasses are also affected. We can demonstrate this quickly with an unusual example that would generally not be used in a real-world system. In this case, we will modify the existing extension method so that it is applied to the Object class, rather than the String class. As every class and structure is derived from System.Object, every class and structure will receive the new member.

Modify the extension method as follows:

public static void OutputToConsole(this object o)
{
    Console.WriteLine(o);
}

At this time, the program will still compile and execute because the string that we are using is a subclass of System.Object. We can improve the example by adding more variables to the Main method:

string testString = "Hello, world.";
testString.OutputToConsole();           // Outputs "Hello, world."

int testInt = 99;
testInt.OutputToConsole();              // Outputs "99"

object testObject = new object();
testObject.OutputToConsole();           // Outputs "System.Object"

Extension Methods and Interfaces

One of the more interesting uses of extension methods is the extending of interfaces. When an extension method is created with the first parameter referring to an interface, all types that implement the interface receive the new method. This provides a manner for attaching real functionality to an interface, rather than providing a signature to be implemented by each class individually. The main limitation is that the extension method may only access members of the interface.

To demonstrate, add the interface shown below to the console application. This interface represents the individual products in a stock inventory system.

public interface IProduct
{
    string StockCode { get; set; }
    int QuantityInStock { get; set; }
    double Price { get; set; }
}

Next, create a new class that implements the IProduct interface, as follows:

class Product : IProduct
{
    public string StockCode { get; set; }
    public int QuantityInStock { get; set; }
    public double Price { get; set; }
}

Finally, we can add an extension method to the IProduct interface. Add this within the existing SampleExtensionMethods class:

public static double StockValue(this IProduct product)
{
    return product.Price * product.QuantityInStock;
}

As the Product class implements the IProduct interface, the new StockValue method is automatically available. Modify the Main method as follows to show the method's operation:

Product p = new Product {StockCode = "RAM", QuantityInStock = 100, Price = 49.99};
double stockValue = p.StockValue();
stockValue.OutputToConsole();           // Outputs "4999"

Guidelines

Extension methods can be very useful. However, because the code for extension methods is held separately from the classes that use them, they can significantly impact the readability of the code. For this reason, it is advisable to only use extension methods where no other option is viable. You should not use extension methods to modify your own assemblies simply to avoid creating a new version of a library.

29 October 2008