Should C# have multiple inheritance? [closed]

I have come across numerous arguments against the inclusion of multiple inheritance in C#, some of which include (philosophical arguments aside):

  • Multiple inheritance is too complicated and often ambiguous
  • It is unnecessary because interfaces provide something similar
  • Composition is a good substitute where interfaces are inappropriate

I come from a C++ background and miss the power and elegance of multiple inheritance. Although it is not suited to all software designs there are situations where it is difficult to deny it's utility over interfaces, composition and similar OO techniques.

Is the exclusion of multiple inheritance saying that developers are not smart enough to use them wisely and are incapable of addressing the complexities when they arise?

I personally would welcome the introduction of multiple inheritance into C# (perhaps C##).


Addendum: I would be interested to know from the responses who comes from a single (or procedural background) versus a multiple inheritance background. I have often found that developers who have no experience with multiple inheritance will often default to the multiple-inheritance-is-unnecessary argument simply because they do not have any experience with the paradigm.


Solution 1:

I've never missed it once, not ever. Yes, it [MI] gets complicated, and yes, interfaces do a similar job in many ways - but that isn't the biggest point: in the general sense, it simply isn't needed most of the time. Even single inheritance is overused in many cases.

Solution 2:

Prefer aggregation over inheritance!

class foo : bar, baz

is often better handled with

class foo : Ibarrable, Ibazzable
{
  ... 
  public Bar TheBar{ set }
  public Baz TheBaz{ set }

  public void BarFunction()
  {
     TheBar.doSomething();
  }
  public Thing BazFunction( object param )
  {
    return TheBaz.doSomethingComplex(param);
  }
}

This way you can swap in and out different implementations of IBarrable and IBazzable to create multiple versions of the App without having to write yet another class.

Dependency injection can help with this a lot.

Solution 3:

One of the issues with dealing with multiple inheritance is the distinction between interface inheritance and implementation inheritance.

C# already has a clean implementation of interface inheritance (including choice of implicit or explicit implementations) by using pure interfaces.

If you look at C++, for each class you specify after the colon in the class declaration, the kind of inheritance you get is determined by the access modifier (private, protected, or public). With public inheritance, you get the full messiness of multiple inheritance—multiple interfaces are mixed with multiple implementations. With private inheritance, you just get implementation. An object of "class Foo : private Bar" can never get passed to a function that expects a Bar because it's as if the Foo class really just has a private Bar field and an automatically-implemented delegation pattern.

Pure multiple implementation inheritance (which is really just automatic delegation) doesn't present any problems and would be awesome to have in C#.

As for multiple interface inheritance from classes, there are many different possible designs for implementing the feature. Every language that has multiple inheritance has its own rules as to what happens when a method is called with the same name in multiple base classes. Some languages, like Common Lisp (particularly the CLOS object system), and Python, have a meta-object protocol where you can specify the base class precedence.

Here's one possibility:

abstract class Gun
{ 
    public void Shoot(object target) {} 
    public void Shoot() {}

    public abstract void Reload();

    public void Cock() { Console.Write("Gun cocked."); }
}

class Camera
{ 
    public void Shoot(object subject) {}

    public virtual void Reload() {}

    public virtual void Focus() {}
}

//this is great for taking pictures of targets!
class PhotoPistol : Gun, Camera
{ 
    public override void Reload() { Console.Write("Gun reloaded."); }

    public override void Camera.Reload() { Console.Write("Camera reloaded."); }

    public override void Focus() {}
}

var    pp      = new PhotoPistol();
Gun    gun     = pp;
Camera camera  = pp;

pp.Shoot();                    //Gun.Shoot()
pp.Reload();                   //writes "Gun reloaded"
camera.Reload();               //writes "Camera reloaded"
pp.Cock();                     //writes "Gun cocked."
camera.Cock();                 //error: Camera.Cock() not found
((PhotoPistol) camera).Cock(); //writes "Gun cocked."
camera.Shoot();                //error:  Camera.Shoot() not found
((PhotoPistol) camera).Shoot();//Gun.Shoot()
pp.Shoot(target);              //Gun.Shoot(target)
camera.Shoot(target);          //Camera.Shoot(target)

In this case, only the first listed class's implementation is implicitly inherited in the case of a conflict. The class for other base types must be explicitly specified to get at their implementations. To make it more idiot-proof, the compiler can disallow implicit inheritance in the case of a conflict (conflicting methods would always require a cast).

Also, you can implement multiple inheritance in C# today with implicit conversion operators:

public class PhotoPistol : Gun /* ,Camera */
{
    PhotoPistolCamera camera;

    public PhotoPistol() {
        camera = new PhotoPistolCamera();
    }

    public void Focus() { camera.Focus(); }

    class PhotoPistolCamera : Camera 
    { 
        public override Focus() { }
    }

    public static Camera implicit operator(PhotoPistol p) 
    { 
        return p.camera; 
    }
}

It's not perfect, though, as it's not supported by the is and as operators, and System.Type.IsSubClassOf().