Multiple Inheritance in C#

There are situations where multiple inheritance is the best (if not the only) choice when designing a certain model for our program or project. C# unfortunately does not support multiple inheritance and so we must look for ways to adapt our design to make possible its implementation. But C# does offer resources and tricks that can be used to simulate multiple inheritance without radically redesigning our class model, with only adding several auxiliary methods and classes and taking one or two precautions while coding them. I propose a design pattern that lets us simulate multiple inheritance in a C# program in a way that produces classes that behave almost like they were really extended from two or more parent classes. We will face classical multiple inheritance problems too and will see how to address them.
Most recent languages like C#, Java, Delphi, have simple inheritance. They don’t have multiple inheritance because their designers had to choose between have it in and have all the problems it comes with, or get it out of the language putting away all those problems, and introduce a versatile and less problematic substitute like interfaces and interface inheritance. Multiple inheritance has multiple problems that we will discuss later. But those problems are quite pathological and do not arise in any program in which multiple inheritance could be useful or could be the most appropriate design.
There are traditional ways to emulate multiple inheritance with interface inheritance with more or less success. Let’s suppose we have two classes, A and B, and we want C to inherit from both of them.

fsdfdsf

class A
{
m1();
}
class B
{
m2();
}
class C : A, B
{
m1();
m2();
}

That code is impossible in C#. The following is the classical workaround to deal with this:

class A
{
m1();
}
interface IB
{
m2();
}
class B : IB
{
m2();
}
class C : A, IB
{
B BObject;
m1();
m2() { BObject.m2(); }
}

In this code, we make class B to implement a new interface named IB that has identical methods as those of B. Then class C inherits from A and IB, and uses an internal B object that replicates B’s m2 method implementation. So C.m2 in fact calls its BObject.m2 method. Then we can say C now has A’s implementation of m1() and B’s implementation of m2(). And we can use C object wherever we could use A objects or IB objects.
But this solution has several problems. One of them is the fact that we can’t use C objects where explicitly B objects are expected, but only where IB objects are. So maybe we will have to change all the other code in the project, replacing references to B objects with references to IB objects. That will not be a big problem if we are designing the model and can take such decisions. But if the project is dependent on third party code or the standard library (the Framework) then we will be unable to make those modifications. Even more important, if class B is not ours, but it is from the standard library or from third party code, we can’t make it implement our IB interface. We can’t touch it.
We have seen that we cannot simulate multiple inheritance completely using only interfaces and simple inheritance. We need something more, and C# happens to have that. Let’s see.
We have these objectives:

  • We want class C to inherit from classes A and B, being able to call their implementation of their methods with no need to rewrite them.
  • We want to be able to use C objects wherever an A object or B object is expected.
  • We don’t want to modify A or B, for they are untouchable for one or another reason, or we simply don’t care.
  • We want to instantiate, reference, and use C objects just like normal objects.
  • We work with parent classes that don’t expose public fields, but use properties instead. However, this pattern will work even if one of the parent classes (at most) exposes public fields.
  • Of course, this pattern works for three or more parents, not only two.

Here is the basic idea:
We will create two auxiliary classes, Aaux and Baux that inherit from A and B respectively.

class A
{
m1();
}
class B
{
m2();
}
class Aaux : A
{
m1();
}
class Baux : B
{
m2();
}

Our new class C won’t inherit from A or B but have the same methods of both of them. Besides, it will contain two objects: one of type Aaux and the other of type Baux. We will call them C.APart and C.BPart respectively. C will use their implementations of m1 and m2 instead of rewriting them.

class C
{
Aaux APart;
Baux BPart;
m1()
{
APart.m1();
}
m2()
{
BPart.m2();
}
}

So every C object has a pair of A and B objects inside. Let’s make those objects know who is containing them by adding a reference to the C object that contains them. We will modify classes Aaux and Baux for this purpose:


class Aaux : A
{
C CPart;
m1();
}
class Baux : B
{
C CPart;
m2();
}

And finally we arrive at the final trick. We will redefine the implicit casting operator for class C, so:

  • Whenever an A object is expected and a C object is found, C.APart is returned.
  • Whenever a B object is expected and a C object is found, C.BPart is returned.

Again, we will redefine the implicit casting operator for class Aaux so whenever a C object is expected and an Aaux object is found, Aaux.CPart is returned. Identically, we will redefine the implicit casting operator for class Baux so whenever a C object is expected and a Baux object is found, Baux.CPart is returned.
This is the final look:

class Aaux : A
{
C CPart;
m1();
static implicit operator C(Aaux a)
{
return a.CPart;
}
}
class Baux : B
{
C CPart;
m2();
static implicit operator C(Baux b)
{
return b.CPart;
}
}
class C
{
Aaux APart;
Baux BPart;
m1()
{
APart.m1();
}
m2()
{
BPart.m2();
}
static implicit operator A(C c)
{
return c.APart;
}
static implicit operator B(C c)
{
return c.BPart;
}
}

Now given that code, we can use C objects wherever an A or B object is expected, in addition to where a C object is expected. The only cost has been adding two extra classes and requiring the parent classes not to expose public fields.
However, there is another step we can take that will allow us to reduce in on the number of extra classes required and will let one of the parent classes have public fields. In fact, the class diagram will be even simpler.

We only have to make C inherit directly from A, the class which exposes public fields.
Of course, properties are fully compatible with this pattern, since they behave like methods. So parent classes may have as many public properties as they wish.

Tagged , . Bookmark the permalink.

Leave a Reply