SIGN UP MEMBER LOGIN:    
ARTICLE

Simulating Multiple Inheritance in C#: Part I

Posted by Vulpes Articles | C# Language March 23, 2011
Here you will see Simulating Multiple Inheritance in C#: Part I
Reader Level:

Introduction

Whilst a class in C# can implement multiple interfaces, it can only inherit from a single class.

This is known as a 'single inheritance model' and is the model used by other popular object oriented languages such as Java and Delphi.

However, some object oriented languages such as C++ and Eiffel support a 'multiple inheritance model' where a class can inherit from several other classes. Although this model suffers from the 'diamond problem' (see http://en.wikipedia.org/wiki/Diamond_problem ), cases do arise in practice where it provides a more natural solution than single inheritance can.

So, is there a way we can simulate multiple inheritance in C# and avoid the diamond problem at the same time?


Proposed Solution

The solution which is usually proposed to deal with the lack of multiple inheritance in C# is 'containment'. This means that the derived class contains (as private fields) objects of each additional parent class and 'wraps' their public members by declaring public members of its own which then delegate to the parent object's members. If any of these members have the same names as existing members of the derived class, then the names are simply changed to avoid conflict.

The following is a simple example of containment though we're going to do the following things slightly differently (you'll see why in Part II of this article):

  1. Instead of inheriting directly from the additional parent class, we're going to inherit from a private nested class which itself inherits from the parent class.
  2. We're going to place the nested class and the wrapped methods for the additional parent class in a separate 'partial class' of the derived class.

using System;

class Father
{
    public void MethodA()
    {
        Console.WriteLine("Hello from Father's MethodA");
    }
}

class Mother
{
    public void MethodA()
    {
        Console.WriteLine("Hello from Mother's MethodA");
    }

    public void MethodB()
    {
        Console.WriteLine("Hello from Mother's MethodB");
    }

    public static void MethodS() // static method
    {
        Console.WriteLine("Hello from Mother's static MethodS");
    }

    public virtual void MethodV() // virtual method
    {
        Console.WriteLine("Hello from Mother's MethodV");
    }
}

partial class Child : Father // add partial modifier
{
    public void MethodC()
    {
        Console.WriteLine("Hello from Child's MethodC");
    }
}

partial class Child : Father // contains Mother inheritance stuff
{
    private NMother base2; // NMother reference

    public Child()
    {
        base2 = new NMother();
    }

    // private nested class which inherits from Mother
    private class NMother : Mother
    {
        // overrides the virtual method Mother.MethodV
        public override void MethodV()
        {
            Console.WriteLine("Hello from Child's MethodV");
        }
    }

    // wraps Mother.MethodA but changes name to MethodD to avoid conflict with Father.MethodA
    public void MethodD()
    {
        base2.MethodA();
    }

    // wraps Mother.MethodB
    public void MethodB()
    {
        base2.MethodB();
    }

    // wraps static method Mother.MethodS
    public static void MethodS() // static method
    {
        NMother.MethodS();
    }

    // wraps override of Mother.MethodV
    public virtual void MethodV()
    {
        base2.MethodV();
    }
}

class GrandChild : Child
{
    // further overrides Mother.MethodV
    public override void MethodV()
    {
        Console.WriteLine("Hello from GrandChild's MethodV");
    }
}

class Test
{
    static void Main()
    {
        Child c = new Child();
        c.MethodA();
        c.MethodB();
        c.MethodC();
        c.MethodD();
        Child.MethodS();
        c.MethodV();
        c = new GrandChild();
        c.MethodV();
        Console.ReadKey();
    }
}


When you build and run this code, the results should be:

Hello from Father's MethodA
Hello from Mother's MethodB
Hello from Child's MethodC
Hello from Mother's MethodA
Hello from Mother's static MethodS
Hello from Child's MethodV
Hello from GrandChild's MethodV

Conclusion


OK, so far so good. The wrapping code is a bit tedious but we can now effectively inherit public methods from an additional parent class (or as many such classes as we like). However, there are still some gaps in the implementation (for example inheriting protected members) which I'll deal with in Part II of this article.
 

Login to add your contents and source code to this article
share this article :
post comment
 

I did not see (and even on a re-read) a link to Part II, and given the publication date was today, I presumed that PArt II would be published at some point in the (near) future. I will keep an eye out for it.

Posted by David Corbin Mar 23, 2011

Thanks for the comment, David, though I suspect you may not have read Part II of the article regarding the 'casting to Mother' point. Whatever you want to call this (I called it a 'simulation' for want of a better readily-understandable word), I'll accept it can get quite complex in 'real life' cases. However, as I've used it successfully myself in recent years, I thought I'd share the technique with others.

Posted by Vulpes Mar 23, 2011

That is *not* a "simulation of Multiple Inheritance" as you can not cast a Child (or GrandChild) to be a Mother. Rather it is asymetric aggregation (Father is aggregated by inheritance while Mother is aggregated by composition). While this approach often "seems good" when looking at simple cases, it quickly becomes a "nightmare" as system complexity increases.

Posted by David Corbin Mar 23, 2011
6 Months Free & No Setup Fees ASP.NET Hosting!
Become a Sponsor
PREMIUM SPONSORS
  • ceTE software specializes in components for dynamic PDF generation and manipulation. The DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and new content to existing PDF documents from within your applications. Visit DynamicPDF here
    Get 2 Months Free of ASP.NET Hosting for Only $4.95/month! Receive FREE MS SQL and MySQL Databases Including ASP.NET 4/3.5, MVC 3.0, Silverlight 4, Windows 2008/IIS 7.0 Plus FREE IIS 7 Modules. Host UNLIMITED ASP.NET Web Sites - Click Here!
Nevron Gauge for SharePoint
Become a Sponsor