多重继承与C#

多重继承与C#,c#,architecture,multiple-inheritance,C#,Architecture,Multiple Inheritance,假设我有两个功能完全不同的基本抽象类:Laptop和Smartphone。(假设功能完全不同)。在我目前的项目中,我已经有很多笔记本电脑和智能手机的实现,它们总是完全不同的 但突然我收到一个请求,要求添加一个类,它是pc平板电脑的一个实现,实际上具有智能手机和笔记本电脑的功能。现在更改基类已经太晚了,事实上我非常确定这款pc平板电脑只会出现一次 问题是,我应该能够在智能手机的conainer中包含我的pc平板电脑,但它也应该是笔记本电脑,因为它继承了原有的功能(事实上,除此之外,在项目的某些部分

假设我有两个功能完全不同的基本抽象类:Laptop和Smartphone。(假设功能完全不同)。在我目前的项目中,我已经有很多笔记本电脑和智能手机的实现,它们总是完全不同的

但突然我收到一个请求,要求添加一个类,它是pc平板电脑的一个实现,实际上具有智能手机和笔记本电脑的功能。现在更改基类已经太晚了,事实上我非常确定这款pc平板电脑只会出现一次

问题是,我应该能够在智能手机的conainer中包含我的pc平板电脑,但它也应该是笔记本电脑,因为它继承了原有的功能(事实上,除此之外,在项目的某些部分,pc平板电脑仅用作笔记本电脑,不需要智能手机功能。此外,在项目的特定部分,将pc平板电脑视为智能手机是不好的)。因此,我有pc平板电脑笔记本电脑:笔记本电脑类,实际上是笔记本电脑,而不是智能手机

我的解决方案是添加一个包装器:

class PcTablet : SmartPhone
{
    private PcTabletAsLaptop _pcTablet;

    // Here goes all the methods of PcTabletAsLaptop as proxies:

    public void Call(int number)
    {
      _pcTablet.Call(number);
     }

     // .....
}
有200多个方法,我希望它们能从PcTabletAsLaptop自动生成


这个解决方案看起来很复杂。我的问题是它好吗,或者有一些更简单的方法可以做到这一点?

我认为你可以从组合而不是聚合的角度来思考


如果您需要多重继承,那么智能手机包含的平板电脑

又如何呢?在大多数情况下,您正在做错事或试图以错误的方式解决问题。下面所示的层次结构如何

internal class PcTabletAslaptop : LaptopBase
{
    // here is you can expose / override laptop specific stuff
}

internal class PcTabletAsSmartphone : SmartphoneBase
{
    // here is you can expose / override smartphone specific stuff
}

public interface IPcTablet
{
   // just expose PcTablet specific API
}

public sealed class PcTablet : IPcTablet
{
   private PcTabletAsSmartphone asSmartphone;
   private PcTabletAsLaptop asLaptop;
}

您可以从智能手机和笔记本电脑中提取接口,然后创建第三个接口PcTablet,该接口将继承前两个接口。这样,您就可以将PcTablet用作智能手机或笔记本电脑

编辑:

为了能够重用每个智能手机和笔记本电脑内部的逻辑,您可以使用适配器模式,使PcTablet看起来像这样:

public class PcTablet :ISmartPhone, ILaptop
{
     private SmartPhone _smartphone;
     private Laptop _laptop;
     public void ISmartPhone.Call()
     {
         _smartPhone.Call();
         // OR IMPLEMENT THE RIGHT BEHAVIOR 
         //INSTEAD OF CALLING _smartPhone.Call()
     }
}

当然,您必须在构造函数中创建smartphone和Lapton,但它应该可以做到这一点!这样,您就可以重用Laptop和smartphone中的代码,但也可以在它们没有提供正确代码的情况下覆盖它们的行为。

您不能再添加一个基类“MobileDevice”吗让他们都继承了吗?200 +方法?也许是时候考虑一些重新设计了。“DaveBISH我不想改变原有的层次结构,因为项目已经在生产了。实际上,这是客户的要求(我们正在编写框架,所以代码设计也被认为是需求的一部分)。@ CysChCLaR,很多移动设备都是C++的DLL,包括最小的逻辑,包括这个。在大多数情况下,这些包装是由第三方生成的,我们没有任何控制权,但是我们有包装源,我们可以改变它们。但是因为C+的任何改变,完全不复存在是不好的。+dll,应该可以从第三方以最小的更改获取包装,但是智能手机和笔记本电脑基类的逻辑呢?我希望它能够以最小的努力被重用。是的,这已经足够好了,这是我的第一个意图。这里唯一让我害怕的是我必须为每个基类实现这些包装智能手机和笔记本电脑的使用方法(很多)@Archeg是的,我理解,但是能够同时将您的PCTablet用作笔记本电脑和智能手机,并且能够重用这两个类中的代码……我看不出有多少其他方法比这更干净。而且它足够灵活,如果它(让我们说调用函数)不能按您想要的方式工作,您可以自由地更改实现,而不会影响到您ng基类。相反,你在基类中所做的所有更改都会影响PCTablet类。它的好坏是同时发生的,但你可以重写该行为!你的解决方案看起来像我的解决方案,因为我已经将PCTablet派生自SmartPhone。我想你的解决方案可能会更好。但我仍然需要改进这200多个方法的代理,PcTablet调用其中一个字段。那么,我的问题是它应该是这样的吗?因此,笔记本电脑和智能手机类的公共API对于PcTablet类来说是不够的,您需要访问受保护/私有接口?如果是这样,当您需要访问私有/受保护接口时,请提供一个示例笔记本电脑/智能手机的王牌?我的意思是PcTabletAsSmartphone有Call()方法,在这种情况下,PcTablet也应该有Call()方法,即调用asSmartphone.Call()。我有200多个这样的方法。由于我隐藏了PcTabletAsSmartphone,我需要将此方法作为代理写入隐藏的内部实例。当然,我可以公开asSmartphone实例,但这将破坏所有设计