C#: a way to get around the lack of multiple implementation inheritance

I run across this question from time to time: why is there no multiple inheritance in C# like there was in C++.  Personally, I've never needed it, but I do see a value to it, and there are some times when it would appear to be handy.

There is a workaround to this problem that is not difficult to do.  You get some of the same abilities as multiple inheritance, with a few structural advantages.  Before I describe the solution (below), let me frame the problem so that we are all using the same terms.

We have two concrete classes.  They are both derived from different base classes (not interfaces).  You want to give both of them a set of common methods and properties that meets a defined interface or base class (multiple inheritance).

Note: if you just want to inherit from an interface and implement the properties and methods directly in the class, you can do that now.  That does not require a workaround.  In other words, it is perfectly acceptable to do this:

   public class MyClass : System.Web.UI.Page , MyNewInterface
   { ... }

So the problem only really arises if you have two or more BASE CLASSES that you want to put on that line... something you cannot do in C#.  I will treat one base class as "given" and one as "add-on".  It really doesn't matter, structurally, which one is which.  There is only one "given" class.  There can be as many "add-on" base classes as you want.

So, you use a simple composition pattern (that I cannot find the name for... if someone knows the name, please send it to me).

Step 1) you need an interface.  This defines a single getter property with a name derived from the base class name of the class you want to add on.

interface IAddOn
{
    // define a getter to return one "AddOnClass" object
    AddOnClass GetAddOn
    {   get;   }
}

Step 2) insure that your concrete object inherits from IAddOn

public class MyMultiConcrete : MyBaseClass, IAddOn
{ .... }

Step 3) Create a factory object that will return a class of type 'AddOnClass'  (optional, but good practice). 

public class AddOnFactory
{
   public static AddOnClass NewAddOnObject()
   {   return new AddOnClass();   // factory method
    }

}

[edited] I want to add one comment here.  You don't have to return a type 'AddOnClass.'  In fact, if the add on class is an abstract class, you cannot.  You would need to derive a class from AddOnClass and then instantiate one of those types.  If you created this class specifically to be called from your new type, then you have a pair of classes that work together.  The derived add-on has access to the private and protected members of the add on type. 

In this case, you can pass in a reference to the calling class:

    public static AddOnClass NewAddOnObject(IAddOn Caller)
    {   return new ConcreteAddOnClass(Caller);   // factory method }

This gives the concrete add on the ability to directly manipulate the 'container' when you call a property or method on it, as shown below.  [end edit]

Step 4) Declare, in your concrete classes, a private property to hold the reference:
      private AddOnClass _AddOn;

Step 5) In the constructor for your concrete class, call your factory object to return an object of type AddOnClass.  Assign the reference to the private _AddOn property.

   public MyMultiConcrete() : base()
   {    // do normal constructor stuff here...
         _AddOn = AddOnFactory.NewAddOnObject();
   }

Step 6) Define the property that returns the add-on object
     public property AddOnClass GetAddOn
     {   Get { return _AddOn; } }

/// you are done ///

Now, every place in  your calling code, where someone needs a method or
property from the add-on type, they will reference it this way:
   MyMultiConcrete.GetAddOn.MyAddOnMethod()

One nice thing to consider, we can do this for as many types as we want within a class.  Therefore, we could theoretically inherit from dozens of base classes. 

I hope you have as much fun using this pattern as I have had describing it.  I doubt that I'm the first person to identify this pattern, so if someone can send me a link to another name or description, I will be grateful.  If not, perhaps I'll go to ChiliPLoP and present it :-).