由于多重继承是不好的(它使源代码更加复杂),c#没有直接提供这样的模式。但有时候拥有这种能力是有帮助的。

例如,我能够使用接口和三个类实现缺少的多重继承模式:

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

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

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(); }
}

每当我向其中一个接口添加方法时,我也需要更改类FirstAndSecond。

是否有一种方法可以像在c++中那样将多个现有类注入到一个新类中?

也许有一种使用某种代码生成的解决方案?

或者它看起来像这样(虚构的c#语法):

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

这样,当我修改其中一个接口时,就不需要更新类FirstAndSecond。


EDIT

也许考虑一个实际的例子会更好:

您有一个现有的类(例如,基于ITextTcpClient的基于文本的TCP客户端),您已经在项目中的不同位置使用它。现在,您觉得有必要创建一个类的组件,以便windows窗体开发人员可以轻松访问。

据我所知,你目前有两种方法来做到这一点:

编写一个从组件继承的新类,并使用类本身的实例实现TextTcpClient类的接口,如FirstAndSecond所示。 编写一个继承TextTcpClient的新类,并以某种方式实现IComponent(实际上还没有尝试过这个)。

在这两种情况下,您都需要为每个方法而不是每个类做工作。因为你知道我们将需要TextTcpClient和Component的所有方法,所以将这两个方法合并到一个类中是最简单的解决方案。

为了避免冲突,这可以通过代码生成来完成,结果可以在之后修改,但手动输入这是一个纯粹的痛苦。


当前回答

在我自己的实现中,我发现在MI中使用类/接口,虽然“形式很好”,但往往过于复杂,因为你需要为几个必要的函数调用设置所有的多重继承,在我的例子中,需要做几十倍的冗余。

相反,简单地在不同的模块化变体中创建静态的“调用调用函数的函数”作为一种面向对象的替代会更容易。我所致力于的解决方案是RPG的“法术系统”,即在不需要重新编写代码的情况下,效果需要大量混合和匹配函数调用来提供各种各样的法术,就像这个例子所表明的那样。

大多数函数现在都可以是静态的,因为我不必为拼写逻辑需要实例,而类继承在静态时甚至不能使用虚拟或抽象关键字。接口根本不能使用它们。

在我看来,这样编码更快更干净。如果只是使用函数,并且不需要继承属性,则使用函数。

其他回答

如果你可以接受IFirst和ISecond的方法只能与IFirst和ISecond的契约交互的限制(就像你的例子一样)……你可以用扩展方法做你想做的事情。在实践中,这种情况很少发生。

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();
}

因此,基本思想是在接口中定义所需的实现……这个需要的东西应该支持扩展方法中的灵活实现。当你需要“向接口添加方法”时,你可以添加一个扩展方法。

考虑只使用组合而不是尝试模拟多重继承。你可以使用接口来定义组成组合的类,例如:isteable暗示了方向盘类型的属性,IBrakable暗示了BrakePedal类型的属性,等等。

一旦你完成了这些,你可以使用c# 3.0中添加的扩展方法功能来进一步简化对这些隐含属性的方法调用,例如:

public interface ISteerable { SteeringWheel 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();
    }
}

在我自己的实现中,我发现在MI中使用类/接口,虽然“形式很好”,但往往过于复杂,因为你需要为几个必要的函数调用设置所有的多重继承,在我的例子中,需要做几十倍的冗余。

相反,简单地在不同的模块化变体中创建静态的“调用调用函数的函数”作为一种面向对象的替代会更容易。我所致力于的解决方案是RPG的“法术系统”,即在不需要重新编写代码的情况下,效果需要大量混合和匹配函数调用来提供各种各样的法术,就像这个例子所表明的那样。

大多数函数现在都可以是静态的,因为我不必为拼写逻辑需要实例,而类继承在静态时甚至不能使用虚拟或抽象关键字。接口根本不能使用它们。

在我看来,这样编码更快更干净。如果只是使用函数,并且不需要继承属性,则使用函数。

是的,使用接口是一个麻烦,因为每当我们在类中添加方法时,我们都必须在接口中添加签名。此外,如果我们已经有一个类有一堆方法,但没有接口怎么办?我们必须手动为所有想要继承的类创建Interface。最糟糕的是,如果子类要从多个接口继承,我们必须在子类中实现接口中的所有方法。

通过遵循Facade设计模式,我们可以使用访问器模拟从多个类继承。在类内部使用{get;set;}将类声明为需要继承的属性,所有公共属性和方法都来自该类,并在子类的构造函数中实例化父类。

例如:

 namespace OOP
 {
     class Program
     {
         static void Main(string[] args)
         {
             Child somechild = new Child();
             somechild.DoHomeWork();
             somechild.CheckingAround();
             Console.ReadLine();
         }
     }

     public class Father 
     {
         public Father() { }
         public void Work()
         {
             Console.WriteLine("working...");
         }
         public void Moonlight()
         {
             Console.WriteLine("moonlighting...");
         }
     }


     public class Mother 
     {
         public Mother() { }
         public void Cook()
         {
             Console.WriteLine("cooking...");
         }
         public void Clean()
         {
             Console.WriteLine("cleaning...");
         }
     }


     public class Child 
     {
         public Father MyFather { get; set; }
         public Mother MyMother { get; set; }

         public Child()
         {
             MyFather = new Father();
             MyMother = new Mother();
         }

         public void GoToSchool()
         {
             Console.WriteLine("go to school...");
         }
         public void DoHomeWork()
         {
             Console.WriteLine("doing homework...");
         }
         public void CheckingAround()
         {
             MyFather.Work();
             MyMother.Cook();
         }
     }


 }

有了这个结构,类Child可以访问父类和母类的所有方法和属性,模拟多重继承,继承父类的实例。不完全一样,但很实用。

您可以有一个实现IFirst和ISecond的抽象基类,然后从该基类继承。