Understanding Extension Methods
.NET 3.5 introduced the concept of extension methods, which allow you to add new methods or properties to a class or structure, without modifying the original type in any direct manner. So, where might this be helpful? Consider the following possibilities.
First, say you have a given class that is in production. It becomes clear over time that this class should support a handful of new members. If you modify the current class definition directly, you risk the possibility of breaking backward compatibility with older code bases making use of it, as they might not have been compiled with the latest and greatest class definition. One way to ensure backward compatibility is to create a new derived class from the existing parent; however, now you have two classes to maintain. As we all know, code maintenance is the least glamorous part of a software engineer’s job description.
Now consider this situation. Let’s say you have a structure (or maybe a sealed class) and want to add new members so that it behaves polymorphically in your system. Since structures and sealed classes cannot be extended, your only choice is to add the members to the type, once again risking backward compatibility!
Using extension methods, you are able to modify types without subclassing and without modifying the type directly. To be sure, this technique is essentially a smoke-and-mirror show. The new functionality is offered to a type only if the extension methods have been referenced for use in your current project.
Defining Extension Methods
When you define extension methods, the first restriction is that they must be defined within a static class and, therefore, each extension method must be declared with the static keyword. The second point is that all extension methods are marked as such by using the this keyword as a modifier on the first (and only the first) parameter of the method in question. The “this qualified” parameter represents the item being extended.
To illustrate, create a new Console Application project named ExtensionMethods. Now, assume you are authoring a class named MyExtensions that defines two extension methods. The first method allows any object to use a new method named DisplayDefiningAssembly() that makes use of types in the System.Reflection namespace to display the
name of the assembly containing the type in question.
The second extension method, named ReverseDigits(), allows any int to obtain a new version of itself where the value is reversed digit by digit. For example, if an integer with the value 1234 called ReverseDigits(), the integer returned is set to the value 4321. Consider the following class implementation (be sure to import the System.Reflection namespace if you are following along):
static class MyExtensions
{
// This method allows any object to display the assembly
// it is defined in.
public static void DisplayDefiningAssembly(this object obj)
{
Console.WriteLine("{0} lives here: => {1}\n",
obj.GetType().Name,
Assembly.GetAssembly(obj.GetType()).GetName().Name);
}
// This method allows any integer to reverse its
digits.
// For example, 56 would return 65.
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);
}
}
Again, note how the first parameter of each extension method has been qualified with the this keyword, before defining the parameter type. It is always the case that the first parameter of an extension method represents the type being extended. Given that DisplayDefiningAssembly() has been prototyped to extend System.Object, every type now has this new member, as Object is the parent to all types in the .NET platform. However, ReverseDigits() has been prototyped to extend only integer types; therefore, if anything other than an integer attempts to invoke this method, you will receive a compile-time error.
.NET 3.5 introduced the concept of extension methods, which allow you to add new methods or properties to a class or structure, without modifying the original type in any direct manner. So, where might this be helpful? Consider the following possibilities.
First, say you have a given class that is in production. It becomes clear over time that this class should support a handful of new members. If you modify the current class definition directly, you risk the possibility of breaking backward compatibility with older code bases making use of it, as they might not have been compiled with the latest and greatest class definition. One way to ensure backward compatibility is to create a new derived class from the existing parent; however, now you have two classes to maintain. As we all know, code maintenance is the least glamorous part of a software engineer’s job description.
Now consider this situation. Let’s say you have a structure (or maybe a sealed class) and want to add new members so that it behaves polymorphically in your system. Since structures and sealed classes cannot be extended, your only choice is to add the members to the type, once again risking backward compatibility!
Using extension methods, you are able to modify types without subclassing and without modifying the type directly. To be sure, this technique is essentially a smoke-and-mirror show. The new functionality is offered to a type only if the extension methods have been referenced for use in your current project.
Defining Extension Methods
When you define extension methods, the first restriction is that they must be defined within a static class and, therefore, each extension method must be declared with the static keyword. The second point is that all extension methods are marked as such by using the this keyword as a modifier on the first (and only the first) parameter of the method in question. The “this qualified” parameter represents the item being extended.
To illustrate, create a new Console Application project named ExtensionMethods. Now, assume you are authoring a class named MyExtensions that defines two extension methods. The first method allows any object to use a new method named DisplayDefiningAssembly() that makes use of types in the System.Reflection namespace to display the
name of the assembly containing the type in question.
The second extension method, named ReverseDigits(), allows any int to obtain a new version of itself where the value is reversed digit by digit. For example, if an integer with the value 1234 called ReverseDigits(), the integer returned is set to the value 4321. Consider the following class implementation (be sure to import the System.Reflection namespace if you are following along):
static class MyExtensions
{
// This method allows any object to display the assembly
// it is defined in.
public static void DisplayDefiningAssembly(this object obj)
{
Console.WriteLine("{0} lives here: => {1}\n",
obj.GetType().Name,
Assembly.GetAssembly(obj.GetType()).GetName().Name);
}
// This method allows any integer to reverse its
digits.
// For example, 56 would return 65.
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);
}
}
Again, note how the first parameter of each extension method has been qualified with the this keyword, before defining the parameter type. It is always the case that the first parameter of an extension method represents the type being extended. Given that DisplayDefiningAssembly() has been prototyped to extend System.Object, every type now has this new member, as Object is the parent to all types in the .NET platform. However, ReverseDigits() has been prototyped to extend only integer types; therefore, if anything other than an integer attempts to invoke this method, you will receive a compile-time error.
End Of This Post
__Please Follow__
0 comments:
Post a Comment