views:

5164

answers:

9

Since multiple inheritance is bad (it makes the source more complicated) C# does not provide such a pattern directly. But sometimes it would be helpful to have this ability.

For instance I'm able to implement the missing multiple inheritance pattern using interfaces and three classes like that:

public interface IFirst { void FirstMethod(); }
public interface ISecond { void SecondMethod(); }

public class First:IFirst 
{ 
    public void FirstMethod() { Console.WriteLine("Frist"); } 
}

public class Second:ISecond 
{ 
    public void SecondMethod() { Console.WriteLine("Second"); } 
}

public class FirstAndSecond: IFirst, ISecond
{
    First first = new First();
    Second second = new Second();
    public void FirstMethod() { first.FirstMethod(); }
    public void SecondMethod() { second.SecondMethod(); }
}

Every time I add a method to one of the interfaces I need to change the class FirstAndSecond as well.

Is there a way to inject multiple existing classes into one new class like it is possible in C++?

Maybe there is a solution using some kind of code generation?

Or it may look like this (imaginary c# syntax):

public class FirstAndSecond: IFirst from First, ISecond from Second
{ }

So that there wont be a need to update the class FirstAndSecond when I modify one of the interfaces.


EDIT

Maybe it would be better to consider a practical example:

You have an existing class (e.g. a text based TCP client based on ITextTcpClient) which you do already use at different locations inside your project. Now you feel the need to create a component of your class to be easy accessible for windows forms developers.

As far as I know you currently have two ways to do this:

  1. Write a new class that is inherited from components and implements the interface of the TextTcpClient class using an instance of the class itself as shown with FirstAndSecond.

  2. Write a new class that inherits from TextTcpClient and somehow implements IComponent (haven't actually tried the yet).

In both cases you need to do work per method and not per class. Since you know that we will need all the methods of TextTcpClient and Component it would be the easiest solution to just combine those two into one class.

To avoid conflicts this may be done by code generation and alter if required but typing this by hand is a pure pain in the ass.

A: 

You could have one abstract base class that implements both IFirst and ISecond, and then inherit from just that base.

Joel Coehoorn
This is probably the best solution, but not necessarily the best idea :p
leppie
wouldn't you still have to edit the abstract class when you add methods to the interafces?
Rik
Rik: just how lazy are you, when you only have to do this once?
leppie
@leppie - "Every time I add a method to one of the interfaces I need to change the class FirstAndSecond as well." This part of the original question isn't addressed by this solution, is it?
Rik
You would have to edit the abstract class, but you NOT have to edit any other classes that depend on it. The buck stops there, rather than continuing to cascade to the entire collection of classes.
Joel Coehoorn
+1  A: 

Oddly enough, I figured out how to do something similar to this here.

plinth
+29  A: 

Consider just using composition instead of trying to simulate Multiple Inheritance. You can use Interfaces to define what classes make up the composition, eg: ISteerable implies a property of type SteeringWheel, IBrakable implies a property of type BrakePedal, etc.

Once you've done that, you could use the Extension Methods feature added to C# 3.0 to further simplify calling methods on those implied properties, eg:

public interface ISteerable { SteertingWheel wheel { get; set; } }

public interface IBrakable { BrakePedal brake { get; set; } }

public class Vehicle : ISteerable, IBrakable
{
    public SteeringWheel wheel { get; set; }

    public BrakePedal brake { get; set; }

    public Vehicle() { wheel = new SteeringWheel(); brake = new BrakePedal(); }
}

public static class SteeringExtensions
{
    public static void SteerLeft(this ISteerable vehicle)
    {
        vehicle.wheel.SteerLeft();
    }
}

public static class BrakeExtensions
{
    public static void Stop(this IBrakable vehicle)
    {
        vehicle.brake.ApplyUntilStop();
    }
}


public class Main
{
    Vehicle myCar = new Vehicle();

    public void main()
    {
        myCar.SteerLeft();
        myCar.Stop();
    }
}
C. Lawrence Wenham
That's the point though - an idea like this would ease composition.
Jon Skeet
Could you provide a link that describes the concept?
spoulson
Very nice explanation. Thank you!
spoulson
yeah, thats a nice use of extension methods!
Nic Wise
Yes, but there are use cases where you really need the methods as part of the main object
David Pierre
Unfortunately member variable data is not accessible in extension methods so you have to expose them as internal or (ug) public, though I think composition by contract is the best way to solve multiple inheritance.
cfeduke
Excellent answer! Concise, easy to understand, very useful illustration. Thank you!
AJ
+1  A: 

I'd like this too - it's what I personally refer to as a mix-in, although I realise it's an overloaded term. I'd like to be able to specify the variable used to implement the interface, with the option to provide my own implementation for specific methods.

I've blogged about this in more detail - although in the context of a deliberate overstatement of what it could mean in terms of inheritance.

I see no reason why this couldn't be implemented in the C# compiler - but it's another bit of language complexity...

Jon Skeet
If C# is to remain useful (i.e. not just for language experts), then I think this is a bad idea.
Mitch Wheat
Due to just the additional complexity for any feature, or because this particular feature is bad?
Jon Skeet
Mitch Wheat, then why add Extension Methods or LINQ or any other new feature? If you don't need it, don't use it. To not provide a tool because some would find it too complex is a joke.
Josh Smeaton
+1  A: 

If you can live with the restriction that the methods of IFirst and ISecond must only interact with the contract of IFirst and ISecond (like in your example)... you can do what you ask with extension methods. In practice, this is rarely the case.

public interface IFirst {}
public interface ISecond {}

public class FirstAndSecond : IFirst, ISecond
{
}

public static MultipleInheritenceExtensions
{
  public static void First(this IFirst theFirst)
  {
    Console.WriteLine("First");
  }

  public static void Second(this ISecond theSecond)
  {
    Console.WriteLine("Second");
  }
}

///

public void Test()
{
  FirstAndSecond fas = new FirstAndSecond();
  fas.First();
  fas.Second();
}

So the basic idea is that you define the required implementation in the interfaces... this required stuff should support the flexible implementation in the extension methods. Anytime you need to "add methods to the interface" instead you add an extension method.

David B
+2  A: 

Multiple inheritance is one of those things that generally causes more problems than it solves. In C++ it fits the pattern of giving you enough rope to hang yourself, but Java and C# have chosen to go the safer route of not giving you the option. The biggest problem is what to do if you inherit multiple classes that have a method with the same signature that the inheritee doesn't implement. Which class's method should it choose? Or should that not compile? There is generally another way to implement most things that doesn't rely on multiple inheritance.

tloach
Please don't judge MI by C++, that's like judging OOP by PHP or automobiles by Pintos. That problem is easily solvable: in Eiffel, when you inherit from a class, you also have to specify which methods you want to inherit and you can rename them. No ambiguities there and no suprises either.
Jörg W Mittag
@JorgSounds like Eiffel is actually doing a mixin...
mP
@mP: no, Eiffel provides true multiple implementation inheritance. Renaming doesn't mean loosing the inheritance chain, nor will it loose the castability of classes.
Abel
A: 

MI is NOT bad, everybody that has (seriously) used it LOVES it and it doesNOT complicate the code! At least not anymore than other constructs may complicate the code. Bad code is bad code regardless of whether or not MI is in the picture.

Anyway, I've got a nice little solution for Multiple Inheritance I wanted to share, it's at; http://ra-ajax.org/lsp-liskov-substitution-principle-to-be-or-not-to-be.blog or you can follow the link in my sig... :)

Thomas Hansen
A: 

Not sure I understand your question well enough to answer but take a look at this article.

Flory
+3  A: 

Since multiple inheritance is bad (it makes the source more complicated) C# does not provide such a pattern directly. But sometimes it would be helpful to have this ability.

C# and the .net CLR have not implemented MI because they have not concluded how it would inter-operate between C#, VB.net and the other lanaguages yet, not because "it would make source more complex"

MI is a useful concept, the un-answered questions are ones like:- "What do you do when you have multiple common base classes in the different superclasses?

Perl is the only language I've ever worked with where MI works and works well. .Net may well introduce it in C# 4.x, the CLR does already support MI but as I've said, there are no language constructs for it beyond that yet.

Until then you are stuck with Proxy objects and multiple Interfaces instead :(

IanNorton
The CLR doesn't support multiple implementation inheritance, only multiple interface inheritance (which is also supported in C#).
Jordão