Monday, May 26, 2008

Extension Methods

Understanding Extension Methods

In .Net when you define any type and want add new method you want add,remove or update any method in the type then you need to recomplile the type.

Under C# 2008, it is now possible to define extension methods. Methods allows existing compiled types (specifically, classes, structures, well as types currently being compiled (such as types in a project to gain new functionality without needing to directly update this technique can be quite helpful when you need to inject which you do not have an existing code base. It can also be quite type to support a set of members (in the interest of polymorphism), type declaration. Using extension methods, you can add functionality providing the illusion these methods were there all along.

Restriction of Extension Methods:

1) The class contains Extension Method it must be static it means all the stuffs inside are static too.

2) The second point is that all extension methods are marked as such by using this keyword as a modifier on the first (and only the first) parameter of the method in question.

3) The third point is that every extension method can be called either from the correct instance in memory or statically via the defining static class.

Define Extension Method: Create a new console application named it MyExtensions. In that make one class MyExtension (Must be static) in that create one extension method which extends integer data type and add method (ReverseDigits) into it to provide facility to reverse the digits.

static MyExtension
{

public static int ReverseDigits(this int i)
{

// Translate int into a string, and then

// get all the characters.

char[] digits = i.ToString().ToCharArray();

// Now reverse items in the array.

Array.Reverse(digits);

// Put back into string.

string newDigits = new string(digits);

// Finally, return the modified string back as an int.

return int.Parse(newDigits);

}

}

Note that first parameter of the extension method and only first parameter of the extension method must contain this parameter which indicates that type of the first parameter is extended. Extension method may contain more than one parameter.

static class TesterUtilClass
{

// Every Int32 now has a Display() method...


public static void Display(this int i)
{ Console.WriteLine("{0} called the Display() method.", i); }

// ...which has been overloaded to take a string!

public static void Display(this int i, string msg)
{ Console.WriteLine("{0} called Display() and told me: {1}", i, msg); }

}

Invoking Extension Method at Instance Level:

Now look as we have defined the reverse digit method in the integer class it will visible to all integers.

static void Main(string [] args)
{

int myint =123456;
Console.WriteLine(“Value of myint {0}, myint);
Console.WriteLine(“Value of reverse myint {0}, myint.ReverseDigit());

// This will give error because Reverse digit method is only visible to integer datatype.
Bool b1 = true;
b1.ReverseDigit();
}

Invoking Extension Method at Static Level:

Recall that the first parameter of an extension method is marked with the this keyword, followed by the type of item the method is applicable to. If we peek at what is happening behind the scenes (as verified by a tool such as ildasm.exe), we will find that the compiler simply calls the “normal” static method, passing in the variable calling the method as a parameter (e.g., it is the value of this).

public static void Main(string [] args)

{

int myint =12345;
Console.WriteLine(“Revers digit Statically”, MyExtension.ReverseDigit(myint));

}

Scope of Extension Method

When you extending any data type in that extended class you can not use any member of data type you are extending means extending type is not same as inheritance. Let’s take one example.

public class mycar
{

public int speed=6;
public int speedup()
{

++speed;

}
}

Now I am going to extend the mycar class.
public static MycarExtended
{

static int DownSpeed(this car c)
{

//This method is drivring from car so you can’t do this.
-- speed;
}

}

On the above method attempting to access the variable speed. Because DownSpeed is static method of MycarExtended speed does not exists in this context. However you can use this parameter to access only public member of the type. See the below example.

public static MycarExtended
{
static int DownSpeed(this car c)
{

//ok
return -- c.speed;
}

}

Importing type that defines Extension Method:

When you partition a set of static classes containing extension methods in a unique namespace,other namespaces in that assembly will make use of the standard C# using keyword to import not only the static classes themselves, but also each of the supported extension methods. This is important to remember, because if you do not explicitly import the correct namespace, the extension methods are not available for that C# code file.

In effect, although it can appear on the surface that extension methods are global in nature,they are in fact limited to the namespaces that define them or the namespaces that import them.Thus, if we wrap the definitions of our static classes (MyExtensions, TesterUtilClass, andCarExtensions) into a namespace named MyExtensionMethods as shown below

namespace MyExtensionMethods

{

static class MyExtensions

{

...

}

static class TesterUtilClass

{

...

}

static class CarExtensions

{

...

}

}

other namespaces in the project would need to explicitly import the MyExtensionMethods namespace to gain the extension methods defined by these types. Therefore, the following is a compiler

error:

// Here is our only using directive.

using System;

namespace MyNewApp

{

class JustATest

{

void SomeMethod()

{

// Error! Need to import MyExtensionMethods

// namespace to extend int with ReverseDigit()!

int i = 0;

i.ReverseDigit ();

}

}

}

Extending Interface Types via Extension Methods

At this point, you have seen how to extend classes (and, indirectly, structures that follow the same syntax) with new functionality via extension methods. To wrap up our investigation of C# 2008 extension methods, allow me to point out that it is possible to extend an interface type with new methods; however, the semantics of such an action are sure to be a bit different from what you might expect.

Create a new Console Application named InterfaceExtensions and define a simple interface
type (
IBasicMath) that contains a single method named Add(). Next, implement this interface on a class type (MyCalc) in a fitting manner. For example:

// Define a normal CLR interface in C#.

interface IBasicMath

{

int Add(int x, int y);

}

// Implementation of IBasicMath.

class MyCalc : IBasicMath

{

public int Add(int x, int y)

{

return x + y;

}

}

Now, assume you do not have access to the code definition of IBasicMath, but wish to add a

new member (such as a subtraction method) to expand its behavior. You might attempt to author the following extension class to do so:

static class MathExtensions

{

// Extend IBasicMath with subtraction method?
public static int Subtract(this IBasicMath itf,int x, int y);

}

However, this will result in compile-time errors. When you extend an interface with new members,you must also supply an implementation of these members! This seems to fly in the face of the very nature of interface types, as interfaces do not provide implementations, only definitions.
Nevertheless, we are required to define our
MathExtensions class as follows:

static class MathExtensions

{

// Extend IBasicMath this method and this
// implementation.

public static int Subtract(this IBasicMath itf,int x, int y)
{

return x - y;

}

}

At this point, you might assume you could create a variable of type IBasicMath and directly
invoke
Subtract(). Again, if this were possible (which it is not), this would destroy the nature of
.NET interface types. In reality, what we have actually said here is “Any class in my project implementing IBasicMath
now has a Subtract() method, implemented in this manner.” As before, all the basic rules apply, therefore the namespace defining MyCalc must have access to the namespace defining MathExtensions. Consider the following Main() method:

static void Main(string[] args)

{

Console.WriteLine("***** Extending an interface *****\n");

// Call IBasicMath members from MyCalc object.

MyCalc c = new MyCalc();

Console.WriteLine("1 + 2 = {0}", c.Add(1, 2));

Console.WriteLine("1 - 2 = {0}", c.Subtract(1, 2));

// Can also cast into IBasicMath to invoke extension.

Console.WriteLine("30 - 9 = {0}",

((IBasicMath)c).Subtract(30, 9));

// This would NOT work!

// IBasicMath itfBM = new IBasicMath();

// itfBM.Subtract(10, 10);

Console.ReadLine();

}

That wraps up our examination of C# 2008 extension methods. Remember that this particular
language feature can be very useful whenever you wish to extend the functionality of a type, even if you do not have access to the original source code, for the purposes of polymorphism. And, much like implicitly typed local variables, extension methods are a key element of working with the LINQ API. As you will see in the next chapter, numerous existing types in the base class libraries have been extended with new functionality (via extension methods) to allow them to integrate with the LINQ programming model.

No comments: