Controlling Inheritance
Article Index
Controlling Inheritance
Access modifiers
Sealed
Nested classes
Extension methods

Extension methods

If you don't have access to the source code of a class and the class is sealed, or you are of the opinion that inheritance is bad and dangerous, what can you do to add functionality without recreating or aggregating the class? Currently the only answer is to use an extension method.

Banner

An extension method is a static method declared within a static class that has a special "pointer" to an instance of the class it extends. The name of the static class, and indeed its namespace, have nothing much to do with the extension method's name and use.

So for example, you could create a general class to be used to hold all the extension methods in your project:

public static class MyExtensions
{

If you want to add a method called MyExtension to MyClass1 the declaration needed is:

 public static void MyExtension(
 this MyClass1 myinstance)
{
  myinstance.MyMethod1();
 }
}

The first parameter specification "this MyClass1" indicates the type that the method is added to and the actual parameter "myinstance" is set to a reference to the instance of MyClass1 that the method has been invoked on. That is, myinstance can be used like "this" in a regular class method and hence it gives access to all of the members of the class.

To use the extension method you simply invoke the method as if it was a regular method defined as part of the class:

MyClass1 myobj2 = new MyClass1();
myobj2.MyExtension();

At this point it looks as if the extension method is exactly the solution we have been looking for. It even allows you to add methods to classes that have been sealed and so provides a way of extending the .NET base class library and fundamental types such as int or bool. However, there are some restrictions on the way that an extension method works and behaves.

The first restriction is that an extension method only has access to the public types of the class it extends. In particular an extension method cannot access private or protected members. An extension method is no more privileged that any code external to the class.

In addition you can't override a class method by an extension method. If you attempt to give an extension method the same name and signature as a class method then the class method is always used in preference.

Notice that no warning is given of the name conflict. This means that extension methods really are only able to extend the behaviour of a class and not modify it. This makes extension safer than inheritance and overriding.

Extension methods are, however, inherited. If you create a MyClass2 which inherits from MyClass1 then a MyClass2 object will have all of MyClass1's extension methods.

This inheritance isn't virtual and hence polymorphism isn't supported. The availability of an extension method depends on the declared type of a reference and not on the type of the instance it actually references. This means that extension method calls are early bound and type checked at compile time.

For example, if MyClass2 inherits from MyClass1 and both declare an extension method MyExtension then MyClass1 will use its version and MyClass2 its version. Notice that there is no need to use new or override to redefine extension methods in derived classes. The rule is that the extension method used by a class is the one that matches its type most accurately.

This matching is done at compile time. For example:

MyClass1 myobj1;
myobj1= new MyClass2();
myobj1.MyExtension();

results in the extension method for MyClass1 being called even though the reference is to an instance of MyClass2. In other words, extension methods are not inherited virtually.

Final thoughts

Inheritance is a powerful idea and it can be misused more easily than used to good effect. The problems usually arise when inheritance chains are long and ad hoc – but long inheritance chains are usually an indication that either the principles of object design are not being used or that the situation is truly complex!

Your choices are to either to attempt to control inheritance piecemeal with access modifiers or forbid it completely using sealed. If you choose not to use inheritance then you need to be aware that the alternatives that you are almost certain to be attracted to carry their own problems and increase your workload. Whatever you do make sure you understand the technology you opt for.

More Deep C#

Banner

<ASIN:0596514824>

<ASIN:1590598849>



 
 

   
RSS feed of all content
I Programmer - full contents
Copyright © 2014 i-programmer.info. All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.