About us

My photo
Laziness is the mother of efficiency. We believe we are efficient guys!!

Thursday, April 28, 2011

Let's play with Extension methods

In this post, I am planning to write about Extension methods in C#.NET. Instead of giving a formal way of introduction, what they are, how they can be used etc., I present it in a FAQ type. (So this will be useful to both interviewers and interviewees!!). If you want a professional approach, I would gladly suggest this MSDN article.


I am just giving an idea about extension methods in C#.NET. Extension methods are available in VB.NET as well. Since I am fluent in C# (compared to VB.NET), I prefer in explaining them in the context of C#. The information given in this post, contains my personal experience with methods. So please bear with me if this is not too professional. :)

OK. Let us start.

Q: What are extension methods?

A: Extension method is a feature introduced in .NET 3.0. It helps us in adding/extending the functionality of a given class. The class could have been developed by us, a third party or even a .NET built-in class also. In essence, it is just a static method resides in a static class, targeting an existing type and extending its functionality. Extension methods are very much useful in LINQ.

Q: Why we need extension methods?

A: When there is a need to extend the functionality of an existing class, we can do one of the following.

1. We can change the code of the class.
Prerequisite : we have to have the source code of the class.
Disadvantage : this will break any running applications.

2. We can inherit the class and make the changes
Disadvantage : If the class is sealed, then we will not be able to inherit it.

3. We can provide a wrapper over the existing class and adding the new functionality as and when needed.
Disadvantage : We have to duplicate the code for wrapping the existing functionality.

4. We can provide a helper class which will provide the additional functionality.
Disadvantage : This is the better solution than the others. Still, this will decrease the readability of the code. Developers have to refer the helper classes even if they just want to understand the functionality.

Extension methods provide a better solution for this issue. These extension methods can be encapsulated in a static class and they can be easily targeted to the desired class. When calling the extended functionality, the consumer of your class will feel as if he/she calls an existing functionality. Still this will keep the readability of the code for the consumers and reviewers.

Q: So, how a typical extension method will look like?

A: As stated earlier, the extension methods reside in a static class and targeting functionality of an existing class. Below is a simple example of using extension methods.

Let us first define a simple class.

public class Person
{
internal string firstName = "";
internal string lastName = "";

public Person(string fName, string lName)
{
this.firstName = fName;
this.lastName = lName;
}

public string GetName()
{

return this.firstName + " " + this.lastName;
}
}

This class encapsulates the first and last name of the person and provides a method which will return the full name in " " format. So we are fine with this class and we started consuming this class in a console application as given below.

class Program
{
public static void Main(string[] args)
{

Person p = new Person("Will", "Smith");

Console.WriteLine(p.GetName());
Console.ReadKey(true);
}
}

The output will be "Will Smith". Now, we find some of the consumers want the name in a different style i.e. ", ". Remember that we have some existing consumers of the Person class, so we cannot change the GetName method. Also for some reasons (either the source code of this class not available, the class is sealed for some reasons, not breaking the existing consumers etc), we would like the Person class remain untouched.

For this, we can use the extension method to provide the desire additional functionality as given below.

public static class PersonExtn
{
public static string GetFullName(this Person person)
{
return person.lastName + ", " + person.firstName;
}
}

And we call this extension method in our console application as follows.

class Program
{
public static void Main(string[] args)
{

Person p = new Person("Will", "Smith");

Console.WriteLine(p.GetName()); // normal method call
Console.WriteLine(p.GetFullName()); // extension method call
Console.WriteLine(PersonExtn.GetFullName(p));
Console.ReadKey(true);
}
}

Now the output will be

Will Smith
Smith, Will

Let us inspect this PersonExten class.

1. We created it as a static class.
2. We added a static method which takes a special kind of parameter "this Person".
3. We provided the desired functionality.

The parameter "this Person" will instruct the compiler that this method is an extension method of type Person. Visual Studio's intellisense will also sense this and will start show this member along with the existing member.

And if you check the console application code, there is no difference between calling an existing method and extension method.

Q: Are extension methods coming from OOPS?

A: No. This feature is introduced in .NET languages and is not coming from OOPS.

Q: Do we have any impact on performance?

A: No. As these are simple static methods (with a special parameter), we will not see a performance impact because of this. Also, these will be converted into a normal method call before written into IL.

i.e.
Console.WriteLine(p.GetFullName());

will be converted to

Console.WriteLine(PersonExtn.GetFullName(p));

So there could not be a performance issue because of extension methods.

Q: Can I still access the static method of the PersonExtn class directly? (as given above)

A: Yes. It is absolutely fine to write like below.

Console.WriteLine(PersonExtn.GetFullName(p));

The only problem is we miss the code readability.


Q: Are there any rules in naming the extension classes?

A: No. It is just another static class, so we can name it as we wish. However, according to the naming guidelines, Extn or Extensions would be correct naming style.


Q: Can I write extension methods to a sealed class?

A: Yes. We can write so. In this way, we can achieve extending functionality, even if we get a third party class as "Sealed" or "NotInheriable" (in VB.NET).

Q: Can a single static class contain different extension methods targeting different types?
A: Yes it is possible. But this will not be perceived as a good practice!

Q: Can I target an extension method to an Interface?

A: Yes. You can. By doing so, we are telling the compiler that, all the classes that implements the given interface, can make use of this extension method. This indeed will be very helpful in providing common functionality across classes.

Q: So, for the case of Abstract classes?

A: Yes! you can. However, since we cannot instantiate an abstract class, we can use this extension method to all its derived non-abstract classes. In other words, we are telling the compiler that, all the non-abstract classes , having the targeted derived class somewhere in the inheritance chain, can make use of this extension method.

Q: Can I overload an existing method with the extension methods?

A: Yes. You can. This will help us in provide us adding functionality in an efficient way. Also you can also overload your own extension methods as well.

Q: Can I call one extension method from the other extension method in the same static class?

A: Yes. As far as you are able to provide the instance it is fine. For example, if the PersonExtn class contains another extension method targeting Person class as below.

public static string GetFullNameVersion2(this Person person)
{
...
}

Then we can call the other extension method GetFullName() inside this GetFullNameVesion2() method, as below.

string s1 = "The Name is " + PersonExtn.GetFullName(person); //calling via static class
string s2 = "The Name is " + person.GetFullName(); //calling via instance


Both will be working fine.

Q: Can the actual type (Person class in this case), can make use of these extension methods?

A: Interestingly Yes! They can use. But in real time, the chances would be very less as we are approaching extension methods since we don't want to modify the actual type.

Q: What happen if an extension method resembles a method in actual type? Will I get any compiler errors?
A: No! In such cases, the instance methods will take the precedence. When the code is executed, the instance method will be called. This provides protection from hackers who try to override the default functionality and do some malfunction.

Q: Do you see some real time advantages of having extension methods?

A: Beyond the above mentioned advantages, we can use extension methods for the below scenario as well. I feel this has enough reasons to go for extension methods even if we have access to the actual type's source code.

Consider the above Person class. When we work on a 3 tier application, we have to pass classes like this (called DTO - carriers of data b/w server and client), to server. If we want to add some pure UI related functionality this class (for example, if we want to call the Console.WriteLine directly inside the methods), we will have issues in server side. Server side, we cannot have any UI related functionality, but we have to have them inside the class at times.

In such cases, we can maintain only the business functionality in the actual type. So now the class is ready to be transported from client to server and vice versa. Now, write all the UI related functionality in extension methods and keep the extension methods class (PersonExtn in this case), in UI layer. By this, the Person class when in UI layer, will contain additional UI functionality and in server side only the business functionality.


So far, I have just given whatever I checked and experienced in Extension methods. I will try to enrich this whenever possible.

Thanks for reading!