![]() |
Languages »
C# »
General
Intermediate
License: The Code Project Open License (CPOL)
Understanding Extension Methods and MixinBy abhigadC# extension methods and Mixin implementation. |
C#, Windows, .NET, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
Extension methods is a powerful concept. We will explore the nuances of extension methods in this article. This article will also look at the Mixin implementation in C#.
An extension method is a static method defined in a non-generic static class, and can be invoked using an instance method syntax. Let’s look at the sample code. Shown here is a very common scenario – evaluate an expression if value is greater than 0.
int NumOne = 10;
if (NumOne > 0)
Console.WriteLine("Number : {0} is greater than 0", NumOne);
Now, this evaluation can be abstracted out to a static method, as follows:
static bool StaticIsGreaterThanZero(int Number)
{
return Number > 0 ? true : false;
}
And, we can revise our if condition as:
if (StaticIsGreaterThanZero(NumOne))
{
Console.WriteLine("Number : {0} is greater than 0", NumOne);
}
By doing this, we don’t have to write an if condition all over our code. Anywhere in the program where we need a logic like if(Number > 0), we can use the StaticIsGreaterThanZero method. In fact, we can promote this method in a separate static class, and use it all over the application. Methods like StaticIsGreaterThanZero are known as helper methods. They add value by centralizing common logic and reducing code duplication / repetition. We all have seen code like this in many applications. Here is the twist – what if we want to make this static method part of the C# integer type? We want to use this static method as an instance method. Let's first code, and then we will evaluate the sample.
public static class ExtensionMethods
{
public static bool IsGreaterThanZero(this int Number)
{
return Number > 0 ? true : false;
}
}
if (NumOne.IsGreaterThanZero())
{
Console.WriteLine("Number : {0} is greater than 0", NumOne);
}
In step 1, we defined a public static class ExtensionMethods and a static method IsGreaterThanZero. Notice, the IsGreaterThanZero method is very much like the StaticIsGreaterThanZero method in terms of code, functionality, and structure. The only difference is the this keyword in the method signature. Extension methods can be created by adding the this keyword in front of the first parameter. IsGreaterThanZero is an extension method. It extends the native int type. That’s why we can write code like NumOne.IsGreaterThanZero(). Extension methods can be used as instance methods. Extension methods will show up in Visual Studio Intellisense, as shown in Figure 1.
What if you want to extend custom types? It is possible to extend existing custom types without changing any code in the underlying type definitions. Here is a sample City type:
public class City
{
private string _name;
private string _state;
public City(string name, string state)
{
this._name = name;
this._state = state;
}
public string Name
{
get
{
return _name;
}
}
public string State
{
get
{
return _state;
}
}
}
We want to extend the City type and add a method to evaluate the city state. This method should return true if the city is in California.
public static bool IsCityinCalifornia(City c)
{
return c.State == "CA" ? true : false;
}
We can add this method in the class, make it a public method, and it will be available as an instance method. Alternatively, we can write IsCityinCalifornia as an extension method without changing the City class.
public static class ExtendCity
{
public static bool IsCityinCalifornia(this City c)
{
return c.State == "CA" ? true : false;
}
}
The IsCityinCalifornia extension method can be used in our evaluation logic as:
City c = new City("Santa Ana", "CA");
City c1 = new City("Bloomington", "IN");
List<city> cities = new List<city>();
cities.Add(c);
cities.Add(c1);
foreach (City _city in cities)
{
//IsCityinCalifornia() is an extension method
if (_city.IsCityinCalifornia())
{
Console.WriteLine("City Name : {0} and City State : {1}",
_city.Name, _city.State);
}
}
Extension methods should be defined in a non-generic, static class. Otherwise, we will get a compile time error. That’s the reason for using a public static class ExtendCity. If an extension method is defined in a different namespace, that namespace can be imported through using the namespace syntax [for example, using ABC.ExtensionMethod;]. What will happen if we add the IsCityinCalifornia method as an instance method in the City type definition in addition to the extension method? As per the documentation, the instance method takes precedence over an extension method. So, the IsCityinCalifornia instance method will be used.
Mixin: Extend the type by extending the interface. A good explanation on mixin in C# can be found on this blog post. Extension methods can be used to implement mixin in C#. Let's look at the code sample.
interface IPerson
{
int age { get; set; }
String name { get; set; }
}
class Person : IPerson
{
private int _age;
private string _name;
#region IPerson Members
public int age
{
get
{
return _age;
}
set
{
if (value > 0)
{
_age = value;
}
}
}
public string name
{
get
{
return _name;
}
set
{
if (!string.IsNullOrEmpty(value))
{
_name = value;
}
else
{
_name = "Unknown";
}
}
}
#endregion
}
static class ExtendIPerson
{
public static bool CanDrive(this IPerson testPerson, bool isDriver)
{
return isDriver;
}
}
static void Main(string[] args)
{
IPerson ip = new Person();
ip.name = "ABC";
ip.age = 21;
if(ip.CanDrive(true))
{
Console.WriteLine(ip.name +" can drive");
}
}
The Person type is extended by extending the IPerson interface. An extension method CanDrive is implemented in the ExtendIPerson static class. This is mixin in C#. Let's summarize the strengths and weaknesses of an extension method. First, weaknesses:
int type will be able to access the extension method as an instance method.dbconnection in our application framework and this application framework is used in multiple applications. We extend the dbconnection in only one application using an extension method. As a result, dbconnection in one application will have more methods as compared to its original definition. This might be confusing for many end users.Person is a base class for the Teacher class. Add a CanDrive instance method in the Person class and add an extension method CanDrive on the Teacher class. An extension method on the Teacher class will never be used. The CanDrive instance method on the Person class is preferred by the compiler.On the positive front, extension methods are the only way to extend third party assemblies / APIs.
System.Linq are implemented as static extension methods.sealed classes.As the documentation says, use extension methods “sparingly”. Extension methods can be used in certain cases where no other solution / trick will work. There are many good examples of extension methods in the .NET framework.
Good articles on Extension methods and Mixin:
Original article.
| You must Sign In to use this message board. | |||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 19 Jul 2008 Editor: Smitha Vijayan |
Copyright 2008 by abhigad Everything else Copyright © CodeProject, 1999-2009 Web19 | Advertise on the Code Project |