Should C# have multiple inheritance?

C#InheritanceMultiple Inheritance

C# Problem Overview


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.

C# Solutions


Solution 1 - C#

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 - C#

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 - C#

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][1].

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().

[1]: http://en.wikipedia.org/wiki/Delegation_pattern "Wikipedia: Delegation Pattern"

Solution 4 - C#

Here is a very useful case for multiple inheritance that I run into all of the time.

As a toolkit vendor, I cannot change published API's or I will break backwards compatibility. One thing that results from that is that I cannot ever add to an interface once I have released it because it would break compilation for anyone implementing it -- the only option is to extend the interface.

This is fine for existing customers, but new ones would see this hierarchy as needlessly complex, and if I were designing it from the beginning, I would not opt to implement it this way -- I have to, or else I will lose backwards compatibility. If the interface is internal, then I just add to it and fix the implementors.

In many cases, the new method to the interface has an obvious and small default implementation, but I cannot provide it.

I would prefer to use abstract classes and then when I have to add a method, add a virtual one with a default implementation, and sometimes we do this.

The issue, of course, is if this class would likely be mixed in to something that is already extending something -- then we have no choice but to use an interface and deal with extension interfaces.

If we think we have this problem in a big way, we opt for a rich event model instead -- which I think is probably the right answer in C#, but not every problem is solved this way -- sometimes you want a simple public interface, and a richer one for extenders.

Solution 5 - C#

C# supports single inheritance, interfaces and extension methods. Between them, they provide just about everything that multiple inheritance provides, without the headaches that multiple inheritance brings.

Solution 6 - C#

Multiple inheritance isn't supported by the CLR in any way I'm aware of, so I doubt it could be supported in an efficient way as it is in C++ (or Eiffel, which may do it better given that the language is specifically designed for MI).

A nice alternative to Multiple Inheritance is called Traits. It allows you to mix together various units of behavior into a single class. A compiler can support traits as a compile-time extension to the single-inheritance type system. You simply declare that class X includes traits A, B, and C, and the compiler puts the traits you ask for together to form the implementation of X.

For example, suppose you are trying to implement IList(of T). If you look at different implementations of IList(of T), they often share some of the exact same code. That's were traits come in. You just declare a trait with the common code in it and you can use that common code in any implementation of IList(of T) -- even if the implementation already has some other base class. Here's what the syntax might look like:

/// This trait declares default methods of IList<T>
public trait DefaultListMethods<T> : IList<T>
{
	// Methods without bodies must be implemented by another 
	// trait or by the class
	public void Insert(int index, T item);
	public void RemoveAt(int index);
	public T this[int index] { get; set; }
	public int Count { get; }
	
	public int IndexOf(T item)
	{
		EqualityComparer<T> comparer = EqualityComparer<T>.Default;
		for (int i = 0; i < Count; i++)
			if (comparer.Equals(this[i], item))
				return i;
		return -1;
	}
	public void Add(T item)
	{
		Insert(Count, item);
	}
	public void Clear()
	{	// Note: the class would be allowed to override the trait 
		// with a better implementation, or select an 
		// implementation from a different trait.
		for (int i = Count - 1; i >= 0; i--)
			RemoveAt(i);
	}
	public bool Contains(T item)
	{
		return IndexOf(item) != -1;
	}
	public void CopyTo(T[] array, int arrayIndex)
	{
		foreach (T item in this)
			array[arrayIndex++] = item;
	}
	public bool IsReadOnly
	{
		get { return false; }
	}
	public bool Remove(T item)
	{
		int i = IndexOf(item);
		if (i == -1)
			return false;
		RemoveAt(i);
		return true;
	}
	System.Collections.IEnumerator 
		System.Collections.IEnumerable.GetEnumerator()
	{
		return GetEnumerator();
	}
	IEnumerator<T> GetEnumerator()
	{
		for (int i = 0; i < Count; i++)
			yield return this[i];
	}
}

And you use the trait like this:

class MyList<T> : MyBaseClass, DefaultListMethods<T>
{
	public void Insert(int index, T item) { ... }
	public void RemoveAt(int index)       { ... }
	public T this[int index] {
		get { ... }
		set { ... }
	}
	public int Count {
		get { ... }
	}
}

Of course, I'm just scratching the surface here. For a more complete description, see the paper Traits: Composable Units of Behavior (PDF).

The Rust language (from Mozilla) has implemented Traits in an interesting way: they noticed that traits are similar to default interface implementations, so they unified interfaces and traits into a single feature (which they call traits). The main difference between traits and default interface implementations (which Java now has) is that traits can contain private or protected methods, unlike traditional interface methods that must be public. If traits and interfaces are not unified into a single feature, then another difference is that you can have a reference to an interface, but you can't have a reference to a trait; a trait is not itself a type.

Solution 7 - C#

I actually miss multiple inheritance for one specific reason... the dispose pattern.

EVERY time that I need to implement the dispose pattern, I say to myself: "I wish I could just derive from a class that implements the dispose pattern with a few virtual overrides." I copy and paste the same boiler-plate code into every class that implements IDispose and I hate it.

Solution 8 - C#

I would argue against multiple inheritance simply for the reason you state. Developers will misuse it. I've seen enough problems with every class inheriting from a utility class, just so you can call a function from every class without needing to type so much, to know that multiple inheritance would lead to bad code in many situations. The same thing could be said about GoTo, which is one of the reasons it's use is so frowned upon. I think that multiple inheritance does have some good uses, just like GoTo, In an ideal world, where they were both only used when appropriately, there would be no problems. However, the world is not ideal, so we must protect bad programmers from themselves.

Solution 9 - C#

YES! YES! and YES!

Seriously, I've been developing GUI libraries my entire career, and MI (Multiple Inheritance) makes this FAR easier than SI (Single Inheritance)

First I did SmartWin++ in C++ (MI heavily used) then I did Gaia Ajax and finally now Ra-Ajax and I can with extreme confident state that MI rules for some places. One of those places being GUI libraries...

And the arguments claiming that MI "is too complex" and such are mostly put there by people trying to construct language wars and happens to belong to the camp which "currently doesn't have MI"...

Just like functional programming languages (like Lisp) have been taught (by the "non-Lispers") as "too complex" by non-functional programming language advocates...

People are afraid of the unknown...

MI RULES!

Solution 10 - C#

I'm happy that C# does not have Multiple Inheritance, even though it would sometimes be convenient. What I would like to see instead is the ability to provide a default implementation of an interface method. That is:

interface I
{
	void F();
	void G();
}


class DefaultI : I
{
	void F() { ... }
	void G() { ... }
}

class C : I = DefaultI
{
	public void F() { ... } // implements I.F
}

In this case, ((I)new C()).F() will call C's implementation of I.F(), while ((I)new C()).G() will call DefaultI's implementation of I.G().

There are a number of issues that the language designers would have to work out before this could be added to the language, but none that are very hard, and the result would cover many of the needs that make Multiple Inheritance desirable.

Solution 11 - C#

I have been working with C# since it was first available as an alpha/beta release and have never missed multiple inheritance. MI is nice for some things but there are almost always other ways to achieve the same result (some of which actually end up being simpler or creating an easier to understand implementation).

Solution 12 - C#

Multiple inheritance in general can be useful and many OO languages implement it one way or another (C++, Eiffel, CLOS, Python...). Is it essential? No. Is it nice to have? Yes.

Solution 13 - C#

Update
I challenge everyone who votes me down to show me any example of multiple inheritance that I can't easily port to a language with single inheritance. Unless anyone can show any such sample, I claim it does not exist. I have ported tons of C++ code (MH) to Java (no-MH) and that was never a problem, no matter how much MH the C++ code used.


Nobody could ever prove so far that multiple inheritance has any advantage over other techniques you mentioned in your post (using interfaces and delegates I can get exactly the same result without much code or overhead), while it has a couple of well known disadvantages (diamond problem being the most annoying ones).

Actually multiple inheritance is usually abused. If you use OO design to somehow model the real world into classes, you will never get to the point where multiple inheritance makes actually sense. Can you provide a useful example for multiple inheritance? Most of the examples I've seen so far are actually "wrong". They make something a subclass, that is in fact just an extra property and thus actually an interface.

Take a look at Sather. It is a programming language, where interfaces do have multiple inheritance, as why not (it can't create a diamond problem), however classes that are no interfaces have no inheritance whatsoever. They can only implement interfaces and they can "include" other objects, which makes these other objects a fixed part of them, but that is not the same as inheritance, it's rather a form of delegation (method calls "inherited" by including objects are in fact just forwarded to instances of these objects encapsulated in your object). I think this concept is pretty interesting and it shows you can have a complete clean OO language without any implementation inheritance at all.

Solution 14 - C#

No.

(for voting)

Solution 15 - C#

one of the truly nice and (at the time) novel things about the DataFlex 4GL v3+ (I know, I know, Data what?) was its support for mixin inheritance - the methods from any other classes could be reused in your class; as long as your class provided the properties that these methods used, it worked just fine, and there was no "diamond problem" or other multiple-inheritance "gotchas" to worry about.

i would like to see something like this in C# as it would simplify certain kinds of abstraction and contruction issues

Solution 16 - C#

Instead of multiple inheritance, you can use mixins which is a better solution.

Solution 17 - C#

I think it would over-complicate things without providing enough ROI. We already see people butcher .NET code with too-deep inheritance trees. I can just imagine the atrocities if people had the power to do multiple inheritance.

I won't deny that it has potential, but I just don't see enough benefit.

Solution 18 - C#

While there are certainly instances where it can be useful, I have found that most of the time when I think I need it, I really don't.

Solution 19 - C#

A colleague wrote this blog about how to get something like multiple inheritance in C# with Dynamic Compilation:

http://www.atalasoft.com/cs/blogs/stevehawley/archive/2008/09/29/late-binding-in-c-using-dynamic-compilation.aspx

Solution 20 - C#

I think its simple really. Just like any other complex programming paradigm, you can misuse it and hurt yourself. Can you misuse objects (oh yes!), but that doesn't mean OO is bad in itself.

Similarly with MI. If you do not have a large 'tree' of inherited classes, or a lot of classes that provide the same named methods, then you will be perfectly fine with MI. In fact, as MI provides the implementation, you'll often be better off than a SI implementation where you have to re-code, or cut&paste methods to delegated objects. Less code is better in these cases.. you can make an almighty mess of sharing code by trying to re-use objects through interface inheritance. And such workarounds don't smell right.

I think the single-inheritance model of .NET is flawed: they should have gone with interfaces only, or MI only. Having "half and half" (ie single implementation inheritance plus multiple interface inheritance) is more confusing than it should be, and not elegant at all.

I come from a MI background, and I'm not scared of or burnt by it.

Solution 21 - C#

I have posted this here a couple of times but I just think it is really cool. You can learn how to fake MI here. I also think the article highlights why MI is such a pain even if that was not intended.

I neither miss it or need it, I prefer to use composition of objects to achieve my ends. That is really the point of the article as well.

Solution 22 - C#

I've used multiple inheritence in C++ myself too, but you really have to know what you're doing in order to not get yourself in trouble, especially if you have two base classes which share a grandparent. Then you can get into issues with virtual inheritence, having to declare every constructor you're going to call down the chain (which makes binary reuse much harder)... it can be a mess.

More importantly, the way the CLI is currently built precludes MI from being implemented easily. I'm sure they could do it if they wanted, but I have other things I'd rather see in the CLI than multiple inheritence.

Things I'd like to see include some features of Spec#, like non-nullable reference types. I'd also like to see more object safety by being able to declare parameters as const, and the ability to declare a function const (meaning that you are guaranteeing that the internal state of an object won't be changed by the method and the compiler double checks you).

I think that between Single Inheritence, Multiple Interface Inheritence, Generics, and Extension Methods, you can do pretty much anything you need to. If anything could improve things for someone desiring MI, I think some sort of language construct which would would allow easier aggregation and composition is needed. That way you can have a shared interface, but then delegate your implementation to a private instance of the class you would normally inherit from. Right now, that takes a lot of boiler plate code to do. Having a more automated language feature for that would help significantly.

Solution 23 - C#

No, we came away from it. You do need it now.

Solution 24 - C#

I prefer C++. I've used Java, C#, etc. As my programs get more sophisticated in such an OO environment, I find myself missing Multiple Inheritance. That's my subjective experience.

It can make for amazing spaghetti code...it can make for amazingly elegant code.

Solution 25 - C#

I believe languages like C# should give the programmer the option. Just because it maybe too complicated does not mean it will be too complicated. Programming languages should provide the developer with tools to build anything the programmer wants to.

You choose to use those API's a developer already wrote, you dont have too.

Solution 26 - C#

Give C# implicits and you will not miss multiple inheritance, or any inheritance for that matter.

Solution 27 - C#

No I do not. I use all other OO features to develop what I want. I use Interface and object encapsulation and I am never limited on what I want to do.

Solution 28 - C#

I try not to use inheritance. The less I can everytime.

Solution 29 - C#

No unless Diamond problem is solved. and you can use composition till this is not solved.

Solution 30 - C#

If we introduce Multiple Inheritance then we are again facing the old Diamond problem of C++...

However for those who think it's unavoidable we can still introduce multiple inheritance effects by means of composition (Compose multiple objects in an object and expose public methods which delegate responsibilities to composed object and return)...

So why bother to have multiple inheritance and make your code vulnerable to unavoidable exceptions...

Solution 31 - C#

I almost don't miss multiple inheritance in C#.

If you are using multiple inhertance to define an actual domain model, then in my experience, you can often create an equally good design using single inheritance and some good design patterns.

Most of the places where I find multiple inheritance to be of real value are the places where it is not the domain itself, but some technology/framework constraint that requires you to use MI. Implementation of COM objects using ATL is a very good example of where you use multiple inheritance to implement all the necessary interfaces that you COM object needs, and an elegant solution to an ugly (compared to .NET) technology. Elegant from the point of view that it is a C++ framework!

I have a situation now though, where I could use multiple inheritance. I have one class that needs to derive features from some other domain object, but it also needs to be accessible for cross-AppDomain calls. This means that it MUST inherit from MarshalByRefObject. So in this particular case, I would really like to derive both from MarshalByRefObject and my specific domain object. That is not possible however, so my class has to implement the same interface as my domain object, and forward calls to an aggregated instance.

But this is, as I said, a case where the technology/framework places a constraint, and not the domain model itself.

Solution 32 - C#

I say no until the Diamond Problem (a big reason why multiple inheritence with classes is bad) is solved adequately and if the solution is as good as using interfaces. In a nutshell, the Diamond Problem basically has to do with potential ambiguity in data, method and events in classes due to multiple inheritence via classes.

P/S You "rarely" avoid a programming solution you badly need just because it is hard. "Difficulty" is no excuse for not having multiple inheritence. Multithreading is hard yet it is available in C#. A big for not having multiple inheritence is due to diamond problem (http://en.wikipedia.org/wiki/Diamond_problem). A smiliar reasoning apply to your comment about better alternatives (people solve and think in different ways so sometimes one solution is a bad idea) and suitable options already exist (why create LINQ when ADO.NET does the trick and is mature...due to the strength of one over the other.)

Solution 33 - C#

It would make things easier, less code, if interfaces could have implementation. But could they be miss-used more than used properly? I think that until you see how it can be done properly, you wont miss it. I get annoyed with the arguments that multiple-inheritance is unsafe. It is not. But almost all language implementations are. But do we NEED it?, I don't know.

I would prefer return type covariance, this can be added easily (just relax the rules, on the return type on over-ridden methods), and is always safe.

example:

class shape {}

class circle : shape {}

interface part {
    shape Form();
}

interface wheel : part {
    circle Form();
}

Solution 34 - C#

Interfaces are multiple inheritance. As a matter of fact, I would consider Java/C# type interfaces the "proper" implementation of multiple inheritance. Forcing multiple inheritance through the use of interfaces, rather then allowing inheritance from multiple concrete or abstract classes forces the developer to use composition/delegation for code reuse. Inheritance should never be used for code reuse and the absence of C++ type multiple inheritance forces developers to come up with better designed classes.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRichard DormanView Question on Stackoverflow
Solution 1 - C#Marc GravellView Answer on Stackoverflow
Solution 2 - C#Chris CudmoreView Answer on Stackoverflow
Solution 3 - C#Mark CidadeView Answer on Stackoverflow
Solution 4 - C#Lou FrancoView Answer on Stackoverflow
Solution 5 - C#David ArnoView Answer on Stackoverflow
Solution 6 - C#QwertieView Answer on Stackoverflow
Solution 7 - C#Brian GenisioView Answer on Stackoverflow
Solution 8 - C#KibbeeView Answer on Stackoverflow
Solution 9 - C#Thomas HansenView Answer on Stackoverflow
Solution 10 - C#Jay BazuziView Answer on Stackoverflow
Solution 11 - C#Scott DormanView Answer on Stackoverflow
Solution 12 - C#Nemanja TrifunovicView Answer on Stackoverflow
Solution 13 - C#MeckiView Answer on Stackoverflow
Solution 14 - C#CrashCodesView Answer on Stackoverflow
Solution 15 - C#Steven A. LoweView Answer on Stackoverflow
Solution 16 - C#Mauricio SchefferView Answer on Stackoverflow
Solution 17 - C#Bob KingView Answer on Stackoverflow
Solution 18 - C#coder1View Answer on Stackoverflow
Solution 19 - C#Lou FrancoView Answer on Stackoverflow
Solution 20 - C#gbjbaanbView Answer on Stackoverflow
Solution 21 - C#FloryView Answer on Stackoverflow
Solution 22 - C#NickView Answer on Stackoverflow
Solution 23 - C#K ManView Answer on Stackoverflow
Solution 24 - C#Paul NathanView Answer on Stackoverflow
Solution 25 - C#Signal9View Answer on Stackoverflow
Solution 26 - C#ApocalispView Answer on Stackoverflow
Solution 27 - C#Patrick DesjardinsView Answer on Stackoverflow
Solution 28 - C#PokusView Answer on Stackoverflow
Solution 29 - C#Vinay PandeyView Answer on Stackoverflow
Solution 30 - C#S M KamranView Answer on Stackoverflow
Solution 31 - C#PeteView Answer on Stackoverflow
Solution 32 - C#PhilView Answer on Stackoverflow
Solution 33 - C#ctrl-alt-delorView Answer on Stackoverflow
Solution 34 - C#user14128View Answer on Stackoverflow