views:

3486

answers:

35

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.

+94  A: 

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.

Marc Gravell
I'm fresh outta votes, so consider this a +1
Rob
Well, you can always come back in a few hours ;-p
Marc Gravell
I've heard similar arguments from developers who come from a procedural programming background. Their argument would be "objects, never had a need for them". Thats missing the point. If they're more expressive they have value (in the right situation).
Richard Dorman
Strictly speaking (and I am just paraphrasing Stroustrup here), that is true, and also it is true that single inheritance is not really needed. Furthermore, classes are not really needed either, right? It is not about "needed" but rather "nice to have"
Nemanja Trifunovic
There are situations where any single feature would help. Does that mean a language should be a kitchen sink with every possible feature you can think of?I don't believe the added complexity burden of multiple inheritance is worth it.
Jon Skeet
If you took objects away, I would miss them sorely; that is the distinction. Objects add massive value at minimal complexity. Multiple inheritance adds (arguably) minimal value at massive complexity.
Marc Gravell
But objects are actually a huge complexity over not having objects. As is the existence of inheritance, interfaces, or any other advanced concept.
Kibbee
OK, let me re-phrase; from my blinkered viewpoint as a .NET developer, /working with objects/ is simple. I know I would fail with MI very quickly. But yes, point taken - object increase complexity. It is about complexity vs reward; objects have big benefits; MI has some benefit, but not enough IMO.
Marc Gravell
Objects are a huge complexity with a commensurate payoff. Single-rooted inheritance has worked for over a decade in Java, about 20 years with Obj-C ... The C# designers were trying to prevent accidental bugs, followed a conventinal design, and (IMHO) did the right thing. Composition > Inheritance!
John Rudy
Marc, have you written code using multiple inheritance? It certainly has complexity, but it's not some horrid untamable beast that it's often made out to be.
Richard Dorman
But it does have a wild side...
Marc Gravell
MI is simple, but if you can't trust yourself not to create a massive tree-like hierarchy, then I think you shouldn't be programming at all.I think the C# designer just wanted to keep life easy for himself, MI is difficult for compilers.
gbjbaanb
Personally, I'd rather find a design that didn't need me (a mere mortal) to *understand* a massive tree-like hierarchy.
Marc Gravell
@Marc: The problem with MI isn't the strange trees, the problem is the diamonds/loops.
tloach
@tloach: true - but I was using that phrase as a direct quote from gbjbaanb
Marc Gravell
then you need to re-read it. I was referring to people who create huge trees and then say 'MI is difficult'. If they used it sensibly, they wouldn't have such self-inflicted problems. Same applies to everything, including objects.
gbjbaanb
@gbjbaanb - fair enough; it could be interpreted in either way, and I chose the wrong one; I see your point, and agree entirely! Sorry for confusion...
Marc Gravell
I haven't missed "stereotypical" multiple inheritance, but I have missed it in the way it's used in the Curiously Recurring Template Pattern (http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern).
Bradley Grainger
you probably didn't missed it because your mind is fixed firmly to the way of thought of single inheritance.. i personally find a lot of uses to it.
Itay
It isn't needed most of the time doesn't mean that in some tiny cases you don't need it.
@Marc, it might be a bit more than a few hours, but that +1 has just landed. Better late than never, eh? =)
Rob
@Rob - lol; nearly 2 years ;p
Marc Gravell
+1 I agree that we don't need MI, since we mostly want it to improve code reuse. But I do think that we need something, maybe some better way to compose our classes. Like with traits or [roles](http://codecrafter.blogspot.com/2010/10/roles-in-c.html).
Jordão
+1  A: 

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.

Bob King
Are you arguing for the compiler to have a hard limit on class inheritance depth?
Mark Cidade
+10  A: 

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.

David Arno
(except maybe state from multiple ancestors... but I'm with you on this one ;-p)
Marc Gravell
@Marc, damn, I knew my sweeping generalisation would come back to bite me. Edited slightly to cover your point :)
David Arno
Similar, but not the same. I would also argue that extension methods come with they're own flavour of complexity. I think CodingHorror had a post on this.
Richard Dorman
+5  A: 

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.

Kibbee
Microsoft made similar assumptions when they introduced VB. They assumed that developers were not smart enough to design good code so the language was dumbed down accordingly. I personally found this offensive and steered away from VB and towards more expressive languages.
Richard Dorman
However, VB.Net has now extended to the point where it is basically has every feature of C#.
Kibbee
Crippling a langauge to keep developers safe isn't really a good design principle. That's a problem that Java has (nothing but classes and interfaces so it's easy to understand...).
Mark Cidade
Read Stroustrup's book on Design and Evolution. He has an uncompromising stand on this: nothing will be kept out of the language just because it will be misused. He was aiming for the competent programmer (and, frankly, I don't want incompetents writing programs anyway).
David Thornley
Nobody wants 'incompetents writing programs'... Unfortunately in the real world a lot of 'incompetents' do, and when they quit or get fired and your get stuck with their masterpieces I'm sure you'll be glad these 'incompetents' at least didn't have MI to mess around with...
kzen
+1  A: 

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.

Dana
+2  A: 

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

Scott Dorman
Not sure I agree. There are situations where MI produces far more elegant solutions than is possible with any of the alterantive techniques discussed in this thread. It does need to be used in right situation and can be abused, but then again so can any of tools in C#s toolbox (extension methods?)
Richard Dorman
+26  A: 

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.

chris
I agree. What you can do with delegation and composition vastly exceeds what you can do with multiple inheritance. And is often the more sustainable solution anyway.
Wedge
You can use mixin here, instead of manually writing the composition :-)
Ron Klein
Absolutely. However, I was trying to illustrate a concept, which is often best done by showing a naive implementation.
chris
Replace "aggregation" with "composition" in your example. If you come from Multiple Inheritance you NEED all the classes in your composed super-class. Here are the differences between `aggregation` and `composition`: http://en.wikipedia.org/wiki/Object_composition#Aggregation
Alex Bagnolini
Yes, you can do this, but it's a pain! If the language supports MI it's cake.
Pete Alvin
+1  A: 

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.

Nemanja Trifunovic
The same can be said about any programming language feature. Contrast C# with assember - all C#'s features are not essential, just REALLY nice to have.
Richard Dorman
True. All programming language features are nice to have.
Nemanja Trifunovic
+1  A: 

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.

Mecki
I agree that is has its complexities (diamond problem being one of them) but it is not possible to fully express multiple inheritance with interfaces, composition or extensions methods (or some combination there of).
Richard Dorman
It may only need you sometimes have to write a little bit more code, but the functionality is absolutely equal. I've ported tons of C++ apps to Java, C++ has MH, Java not, it never was a problem to port any of these, I have the same classes and same interfaces (and just some extra classes)
Mecki
It's not a question of getting it to work, it's a question of getting the code you want. I gave an example where MI would help me (wanting to add methods to released interfaces that can't change -- easy to do with abstract classes, but only if MI is available).
Lou Franco
@Lou: You don't need MI for that. Okay, I think Java can't do that, but Objective-C can do that (we regularly extend Apple's own classes with own methods) and Objective-C has no MI.
Mecki
A: 

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

Lou Franco
+1  A: 

No.

(for voting)

CrashCodes
A: 

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.

gbjbaanb
A: 

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.

Flory
The article mentions precisely one problem with MI: the diamond pattern. To avoid the possibility of that, it goes into detail on fairly complicated work-arounds to implement MI. I'm not impressed with the reasoning: wouldn't it be simpler just to have MI and say "DON'T DO THE DIAMOND!"?
David Thornley
A: 

Yes.

(for voting)

sep332
Make this a community wiki. Don't expect reputation points for posting a voting option!
Mark Cidade
Hadn't thought of it that way.How do you recommend I help "make this a community wiki"?
sep332
I didn't realize either. I know the question asked for more than just Yes or No, but I wanted to see yes/no I wasn't trolling for rep. Anyway, I went back and edited my post and checked the community wiki box. You should too.
CrashCodes
+9  A: 

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.

Lou Franco
A: 

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.

Nick
+3  A: 

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

Qwertie
Interesting suggestion. How is this different to using a helper class or aggregation?
Richard Dorman
How could you implement IList with aggregation or helper class (assuming you already have a base class that doesn't implement IList)? Without traits you'd still have the burden of implementing every method of IList. Besides, there are other benefits of traits--you'd have to read the paper.
Qwertie
I also think that traits would be a great addition to C#, and that it would completely supercede the need for multiple inheritance. There's already research to add traits to C#: http://scg.unibe.ch/archive/projects/Reic05a.pdf Let's just hope that one day it comes to fruition.
Jordão
+16  A: 

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

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

If you look at C++, the kind of inheritence you get from each class you specify after the colon in the class declaration is determined by the access modifier (private, protected, or public). With public inheritence, you get the full messiness of multiple inheritence--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 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 inheritence from classes, there are many different possible designs for implementing the feature. Every language that has multiple inheritence 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 inheritence in the case of a conflict (conflicting methods would always require a cast).

Also, you can implement multiple inheritence 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().

Mark Cidade
+++ on this one for me. Eiffel and Sather are good examples of multiple inheritance done right.www.icsi.berkeley.edu/~sather/
mancaus
In Sather a class exposes no interface other than that defined by the interfaces it "inherits". Implementation inheritance is via an "include" keyword that does just that, but allows renaming to avoid namespace conflicts. Sather also had many other features only recently introduced into C#.
mancaus
Great response. The use of implicit operators is an interesting approach but unfortunately doesn't come with the benefits of the compiler understanding an MI tree. The correctness of any inheritance tree needs to be maintained by the developer.
Richard Dorman
A good use of multiple inheritance in C++ was as a way to implement mixins (http://en.wikipedia.org/wiki/Mixin). I think that native C# support for mixins (or private implementation inheritance) would be a helpful feature.
Bradley Grainger
+1. To the other comments about mixins: Thats why Objective-C has Categories (effictively mixins) and doesnt need MI for that reason.
Johannes Rudolph
A: 

No, We came away from it. You do u need it now

K Man
A: 

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.

Paul Nathan
A: 

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.

interfaces provide specifications, not reusable code; they are contracts, not inheritance
Steven A. Lowe
akramnik - wtf is wrong with you
+1  A: 

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.

Jay Bazuzi
A new take. Interesting
Varun Mahajan
How is that not the same thing as multiple inheritance?
kitchen
@kitchen: It is multiple inheritance, but only of interfaces, which is already allowed in C#. It doesn't bump in to any of the MI issues that come from inheriting *implementation*.
Jay Bazuzi
It does, though, if you're allowing them to provide a default interface (a default implementation) i.e: "class Foo : IBar = Bar, IBaz = Baz { ... }"
kitchen
@Jay: I agree with kitchen: what you are asking for is multiple inheritance. It is inheritance of interface, inheritance of behavior, and represents an IS-A relationship. Inheritance in C++ is precisely that. I am interested in understanding what you think MI actually is, if not this.
David Thornley
C IS-A I, but AINT-NO DefaultI.You can inherit from multiple interfaces in C# already, but only from one base class, and I'm not proposing a change to that rule.
Jay Bazuzi
+1  A: 

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

Steven A. Lowe
+3  A: 

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.

Brian Genisio
Great example of a positive example use of MI !
Kieren Johnstone
Actually, what I realized is that I don't need multiple inheritance... what I really need is mix-ins. THAT would let me bring in the Dispose pattern code without needing multiple inheritance.
Brian Genisio
A: 

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.

Signal9
+2  A: 

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!

Thomas Hansen
Could you give an example?
Kieren Johnstone
A: 

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

Apocalisp
A: 

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.

Daok
A: 

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

Pokus
A: 

c# does include multiple inheritance. its called c++.

+1  A: 

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

Mauricio Scheffer
A: 

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

S M Kamran
A: 

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 problem 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.

Pete
A: 

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%5Fproblem). 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.)

Phil
+1  A: 

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

Vinay Pandey