Extension Methods
Open Closed Principle(OCP)
states that we
should design our types in such a way that it should be open for extension but
closed for modification. Extension methods in C# can be thought of as a
mechanism to implement the OCP
for user defined
types or even the primitive types and the types defined in the framework.
Extension
methods allow us to extend an existing type by adding additional methods and
functionality to an existing type without needing to change the code of that
type(we might even not have code in most cases). Prior to the existence of
extension methods, developers used to create their own types and either inherit
or contain the existing type inside these types. These new types were more of
the
wrappers
on the existing
types rather than the actual extensions of these types.
For example
if we needed to have the functionality of getting the negative of an integer
then I will have to wrap my integer in a custom type and then use this custom
type to perform the operation.
// Old way of extending using wrapper classes
struct MyInt
{
int value;
public MyInt(int val)
{
this.value = val;
}
public int Negate()
{
return -value;
}
}
static void Main(string[] args)
{
// Old way of using wrappers for extensions
MyInt i = new MyInt(53);
Console.WriteLine(i.Negate());
}
Now
this approach did work but the problem is that we are not at all
extending the existing type. We are creating a new type
all together that is wrapping the existing type and then providing us
the desired functionality.
So
if we really want to extend a method we should be able to add this method
Negate
in the int type only
and everyone should be able to call this method on int
type only. No need
to create another type to have this additional functionality. Extension methods
provides just the same thing. Using extension methods we can write the
custom functionality and can hook them with the existing types so
that they can be used on those types.
To
create an extension method, we need to take the following steps:
1. Define a
static
class.
2. Define a
public static
function in this
class with the name desired as the mew method name and return value as per the
functionality.
3. Pass the parameter
of type that you want to extend. The important thing here is to put a
this
keyword before the
parameter to tell the compiler that we need to extend this type and we are not
really expecting this type as argument.
So
lets try to add this
Negate
function in the int
type.
Extension
Methods
Open Closed Principle(OCP)
states that we should design our types in such a way that
it should be open for extension but closed for modification. Extension methods
in C# can be thought of as a mechanism to implement the OCP
for user defined types or even the
primitive types and the types defined in the framework.
Extension methods allow us to extend an existing type by adding
additional methods and functionality to an existing type without needing to
change the code of that type(we might even not have code in most cases). Prior
to the existence of extension methods, developers used to create their own
types and either inherit or contain the existing type inside these types. These
new types were more of the
wrappers
on the
existing types rather than the actual extensions of these types.
For example if we needed to have the functionality of
getting the negative of an integer then I will have to wrap my integer in a
custom type and then use this custom type to perform the operation.
Hide Copy Code
// Old way of extending using wrapper classes
struct MyInt
{
int value;
public MyInt(int val)
{
this.value = val;
}
public int Negate()
{
return -value;
}
}
static void Main(string[] args)
{
// Old way of using wrappers for extensions
MyInt i = new MyInt(53);
Console.WriteLine(i.Negate());
}
Now this approach did work but the problem is that we
are not at all extending the existing type. We are creating a new type
all together that is wrapping the existing type and then providing us
the desired functionality.
So if we really want to extend a method we should be able to add
this method
Negate
in the
int type only and everyone should be able to call this method on int
type only. No need to create another type
to have this additional functionality. Extension methods provides just the same
thing. Using extension methods we can write the
custom functionality and can hook them with the existing types so
that they can be used on those types.
To create an extension method, we need to take the following
steps:
1. Define
a
static
class.
2. Define
a
public
static
function
in this class with the name desired as the mew method name and return value as
per the functionality.
3. Pass
the parameter of type that you want to extend. The important thing here is to
put a
this
keyword
before the parameter to tell the compiler that we need to extend this type and
we are not really expecting this type as argument.
So lets try to add this
Negate
function
in the int type.
Hide Copy Code
// Extending using Extension methods
static class MyExtensionMethods
{
public static int Negate(this int value)
{
return -value;
}
}
static void Main(string[] args)
{
//Using extension method
int i2 = 53;
Console.WriteLine(i.Negate());
}
Now using extension method let us define the methods on some
existing type. Now what if we want the new method to accept some parameters.
Well to do this we can define additional parameters after the first parameter
that is of the type to be extended (used with
this
keyword . Let define one more
function in int
calledMultiply
to see
this in action.
Hide Copy Code
// Extending using Extension methods
static class MyExtensionMethods
{
public static int Negate(this int value)
{
return -value;
}
public static int Multiply(this int value, int multiplier)
{
return value * multiplier;
}
}
static void Main(string[] args)
{
// Passing arguments in extension methods
int i3 = 10;
Console.WriteLine("Passing arguments in extension methods: {0}", i3.Multiply(2));
}
Now there are two points that need to be remembered before
implementing extension methods.
·
First of which is that the extension methods can only access the
public
properties
of the type.
·
The extension method signature should not be same as an existing
method of the type.
·
The extension method for a type can only be used if the
namespace that contains the extension method is in scope.
·
In case we define extension methods in such a way that it
overloads an existing method of the original type and the calls are
getting ambiguous then the overload resolution rule will always
choose the instance method over the extension method.
·
If there is some ambiguity between two extension methods then
the method containing more specific arguments will get called.
If we keep the following point in mind we could really utilize
the extension methods to better design and extend the types and provide better
abstraction of the type.
LINQ
uses
extension methods heavily. It is highly recommended to look at how LINQ
used extension methods in conjunction with LAMBDA
expression.// Extending using Extension methods
static class MyExtensionMethods
{
public static int Negate(this int value)
{
return -value;
}
}
static void Main(string[] args)
{
//Using extension method
int i2 = 53;
Console.WriteLine(i.Negate());
}
Now
using extension method let us define the methods on some existing type. Now
what if we want the new method to accept some parameters. Well to do this we
can define additional parameters after the first parameter that is of the type
to be extended (used with
this
keyword . Let
define one more function in int
calledMultiply
to see this in
action.// Extending using Extension methods
static class MyExtensionMethods
{
public static int Negate(this int value)
{
return -value;
}
public static int Multiply(this int value, int multiplier)
{
return value * multiplier;
}
}
static void Main(string[] args)
{
// Passing arguments in extension methods
int i3 = 10;
Console.WriteLine("Passing arguments in extension methods: {0}", i3.Multiply(2));
}
Now
there are two points that need to be remembered before implementing extension
methods.
·
First
of which is that the extension methods can only access the
public
properties of the
type.
·
The
extension method signature should not be same as an existing method of the
type.
·
The
extension method for a type can only be used if the namespace that contains the
extension method is in scope.
·
In
case we define extension methods in such a way that it overloads an existing
method of the original type and the calls are getting ambiguous then
the overload resolution rule will always choose the instance method over the
extension method.
·
If
there is some ambiguity between two extension methods then the method
containing more specific arguments will get called.
If
we keep the following point in mind we could really utilize the extension
methods to better design and extend the types and provide better abstraction of
the type.
LINQ
uses extension
methods heavily. It is highly recommended to look at how LINQ
used extension
methods in conjunction with LAMBDA
expression.
No comments:
Post a Comment