From .NET framework 3.0, a very useful feature named extension method was added. This is simple to understand and use and developers would be happy to know about it.
Objective
To see what the Extension methods are and how they work.
Introduction and background
In object oriented world, the extension is implemented by inheriting the classes/types and adding functionality in the derived class/ type. This in an important feature of OOPS and also a great tool to promote reusability and productivity. So far so good, what about the already deployed types which would need some additional functionality /features? The known and traditional way is to change the deployed types, recompile, update the production environment and inevitably break something here and there. Such changes also demands extensive QA and testing efforts to make sure things are not breaking but even after doing this, there is risk of breaking the client code. In addition to this many types are of sealed types e.g. System.String which prevents the modification.
So do we have any solution? Fortunately the answer to this question is YES. Talking about C#, such feature is available from C# 3.0 and it provides simple mechanism to extend types in the system (reference, value, and interface types) and it can be employed also for custom types. If one looks into the framework, one can know that such mechanism (Extension Methods) have played major role in LINQ evolution. This mechanism is straightforward and easy to understand and implement.
Description
Let’s start with some facts or rules for extension methods.
Rules for Extension methods
Here are a couple of facts/rules/ guidelines to consider in case of extension methods:
- Method’s first parameter specifies which type the method operates on, and the parameter is preceded by the “this” modifier
- Extension methods are defined as static methods but are called by using instance method syntax
- 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
- At compile time, extension methods always have lower priority than instance methods defined in the type itself.
- The concept of extension methods cannot be applied to fields, properties or events
- Use extension methods sparingly....too much of it is not good thing!!
We will discuss two simple examples and these examples would be executed through console application. Examples are in C# and exercise is done as console application.
Example1: Extending the type in system
Int32 type would be extended to have a method to show no. of digits in an Int32 number.
public static class Int32Extension
{
/// <summary>
/// This is an extension method. The first parameter to this method takes "this" modifier and also specifies
/// the type for which method is defined. This specific method return the no of digits in a number.
/// </summary>
/// <param name="number"></param>
/// <returns></returns>
public static int DigitCount(this Int32 number)
{
Console.WriteLine("In extended method 'DigitCount'");
return number.ToString().Length;
}
}
Example2: Extending the custom type
We have defined a type named “Person” in a class library called as ‘POCO’ (Plain Old CLR Objects).
This type doesn’t have method for showing the full name which would be achieved through having an extension method.
namespace POCO
{
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string MiddleName { get; set; }
public int PersonId { get; set; }
public Person(string firstName, string lastName, string middleName)
{
this.FirstName = firstName;
this.LastName = lastName;
this.MiddleName = middleName;
}
public string PersonName
{
get { return FirstName + " " + LastName; }
}
}
**********************************************************************************
using POCO;
namespace ExtensionMethods
{
public static class PersonExtension
{
/// <summary>
/// This is an extension method for the custom type called 'Person'. This type is already in deployed environment and there is
/// need to have functionality to return the person's full name. This method performs this by extension.
/// </summary>
/// <param name="number"></param>
/// <returns></returns>
public static string ShowPersonFullName(this Person person)
{
Console.WriteLine("In extended method 'ShowPersonFullName'");
string name = string.Format("The Full name of the person is {0} {1} {2}", person.FirstName,
person.MiddleName, person.LastName);
return name;
}
}
}
Console application
static void Main(string[] args)
{
Console.WriteLine("***************Extending System Type***************");
Int32 testInteger = 654564654;
Console.WriteLine("Invoking the extension method named 'DigitCount'");
int count = testInteger.DigitCount(); //invoking the extension method
Console.WriteLine("The count of digits in the number is " + count.ToString());
Console.WriteLine("***************Extending Custom Type***************");
POCO.Person newPerson = new POCO.Person("Tom", "Dick", "Harry");
Console.WriteLine("Invoking the extension method named 'ShowPersonFullName'");
Console.WriteLine(newPerson.ShowPersonFullName());
}
Output:
***************Extending System Type***************
Invoking the extension method named 'DigitCount'
In extended method 'DigitCount'
The count of digits in the number is 9
***************Extending Custom Type***************
Invoking the extension method named 'ShowPersonFullName'
In extended method 'ShowPersonFullName'
The Full name of the person is Tom Harry Dick
Summary
The output demonstrates the power and use of extension methods. We have explored the extension of system and custom types. Also we elaborated some facts/ rules for using extension methods. The implementation of extension method in the context of LINQ is out of scope for this discussion.
Conclusion
This is very good feature provided by Microsoft in .NET framework which facilitates the extension of types without need to change the types, recompile. These are specifically useful when the types are already deployed and the efforts and cost for changing such types and redeploying them is high. Also changing types make cause lot of breaking in the client code (where they are used) or the other related types. Extension methods solve this issue seamlessly. For a client code (callee code), there is no difference instance method or extension methods. Of course extension methods shall be used with caution giving due thought to need of such methods, deployment of such methods (through types) and weighing whether the change in original type would be beneficial or not.
References: