Miguel A. Castro's Blog

# Sunday, September 05, 2010

Got your attention yet?  Well, truth be told, it doesn’t really have multiple inheritance; not in the true sense.  However, with a little creativity in technique, and provided your needs are not too deep, you can simulate a pseudo-multiple-inheritance scenario.  So let’s start by totally stating the obvious.

We have BaseClass1 and BaseClass2, each with methods that write out to the console a message identifying themselves.

 

public class BaseClass1
{
    public void BaseMethod1(string arg1, bool arg2)
    {
        Console.WriteLine(string.Format("BaseMethod1 in BaseClass1 called with arguments: {0} & {1}.", arg1, arg2.ToString()));
    }

    public void BaseMethod2(string arg1, string arg2)
    {
        Console.WriteLine(string.Format("BaseMethod2 in BaseCall1 called with arguments: {0} & {1}.", arg1, arg2));
    }
}

public class BaseClass2
{
    public void BaseMethod1(string arg1, bool arg2)
    {
        Console.WriteLine(string.Format("BaseMethod1 in BaseClass2 called with arguments: {0} & {1}.", arg1, arg2.ToString()));
    }

    public void BaseMethod2(string arg1, string arg2)
    {
        Console.WriteLine(string.Format("BaseMethod2 in BaseCall2 called with arguments: {0} & {1}.", arg1, arg2));
    }
}

 

Now we have a couple of other classes which have their own methods and each also inherits from one of the base classes.  We all know that .NET will limit the inheritance to only one class.

 

public class DerivedClass1 : BaseClass1
{
    public void DerivedMethod1()
    {
        Console.WriteLine("DerivedMethod1 in DerivedClass1 called.");
    }
}

public class DerivedClass2 : BaseClass2
{
    public void DerivedMethod1()
    {
        Console.WriteLine("DerivedMethod1 in DerivedClass2 called.");
    }
}

 

If I instantiate these two classes, I can call either their own methods or the ones declared in the base class, right? 

 

DerivedClass1 dc1 = new DerivedClass1();
dc1.BaseMethod1("hello", true);
dc1.BaseMethod2("hello", "world");
dc1.DerivedMethod1();

DerivedClass2 dc2 = new DerivedClass2();
dc2.BaseMethod1("hello", true);
dc2.BaseMethod2("hello", "world");
dc2.DerivedMethod1();

 

Have I insulted your intelligences enough by stating the obvious in about as boring fashion possible?  Well I did that for a reason.  See, my needs are to give the functionality provided  by both base classes to a derived class and still keep it apart in two separate entities; only my so-called entities won’t be classes this time, they’ll be extension methods.

Extension methods, introduced in .NET 3.5, allow me to add functionality in the for of methods to existing types.  This is a little like subclassing the type, but in a different way.  You can add extension methods to types that are sealed, and don’t accept subclassing.  You can also add them to classes that meet a certain contract or more specifically, implement a specific interface.  That’s the technique I’m gong to use now.

As you more than likely know, .NET types can only derive from a single type, but they can implement as many interfaces as you need.   So the firs thing I’m going to do is refactor my base classes so they are interfaces instead.  Yeah, I know, interfaces don’t offer implementation, just definition.  Don’t worry I’ll get to that.  What you’ll notice though is the simplicity of my two interfaces

 

public interface IBase1
{
}

public interface IBase2
{
}

 

By simplicity I mean, emptyness.  These interfaces are basically just marker interfaces and will contain no definitions for anything.   What they will do is offer an abstraction on which to define an extension, using extension methods.  Extension methods are defined as static methods first of all.  In fact, the way we code them is simply syntactic sugar for the actual static methods into which the language compiler will turn them.  The first argument of each static method will correspond to the type I want to “extend”, and is identified as such with the word this in front of it.

 

public static class Base1Extensions
{
    public static void Base1Method1(this IBase1 baseClass, string arg1, bool arg2)
    {
        Console.WriteLine(string.Format("BaseMethod1 from IBase1 called with arguments: {0} & {1}.", arg1, arg2.ToString()));
    }

    public static void Base1Method2(this IBase1 baseClass, string arg1, string arg2)
    {
        Console.WriteLine(string.Format("BaseMethod2 from IBase1 called with arguments: {0} & {1}.", arg1, arg2));
    }
}

public static class Base2Extensions
{
    public static void Base2Method1(this IBase2 baseClass, string arg1, bool arg2)
    {
        Console.WriteLine(string.Format("BaseMethod1 from IBase2 called with arguments: {0} & {1}.", arg1, arg2.ToString()));
    }

    public static void Base2Method2(this IBase2 baseClass, string arg1, string arg2)
    {
        Console.WriteLine(string.Format("BaseMethod2 from IBase2 called with arguments: {0} & {1}.", arg1, arg2));
    }
}

 

Notice that in these methods, the first argument is of the type of one of the two interfaces.  Extension methods don’t have to extend specific types, they can also extend classes that implement a certain interface or inherit from a certain base class.  In this case, the former.  Notice that the implementation for each of these four methods is identical to the implementations defined earlier in BaseClass1 and BaseClass2.  All four of these methods could have been placed into one static class, since the class does nothing more than provide housing for the methods.  But I chose to split them up to better mimic the original base-class scenario.

Now I can attach the functionality provided by these methods any class, simply by implementing the appropriate interface.

 

public class DerivedClass3 : IBase1, IBase2
{
    public void DerivedMethod1()
    {
        Console.WriteLine("DerivedMethod1 in DerivedClass3 called.");
    }
}

 

Now, DerivedClass3 can call any extension method designed to extend the IBase1 or IBase2 interfaces.

 

DerivedClass3 dc3 = new DerivedClass3();
dc3.Base1Method1("hello", true);
dc3.Base1Method2("hello", "world");
dc3.Base2Method1("hello", true);
dc3.Base2Method2("hello", "world");
dc3.DerivedMethod1();

 

This does have its limitations.  Unlike a true base-class scenario, the code in each extension method can only access members of the type it is extending.  And in this case, that type is an interface and an empty one at that.  So obviously, this technique is useful only when the implementation code you want is not going to need any outside dependencies, while methods in a true base class can depend on other members of that base class.  Another limitation is that extension methods can only be just that, methods.  This technique would not work if you’re looking to simulate property inheritance.

So there you have it, multiple inheritance in .NET – ok maybe not, but pretty cool huh?

 

Until next time…

Sunday, September 05, 2010 12:12:29 AM (Eastern Daylight Time, UTC-04:00)  #    Comments [3] - - Follow me on Twitter
Dev Stuff
Search
Me & My Flair

Read all about me here.
Download my Resume here.

Check out where I am here.
 
Click on logos above for profiles.
Archive
<September 2010>
SunMonTueWedThuFriSat
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789
Statistics
Total Posts: 40
This Year: 0
This Month: 0
This Week: 0
Comments: 93