【问题标题】:c# multiple inheritancec# 多重继承
【发布时间】:2011-01-16 10:50:57
【问题描述】:

我想在 C# 中实现这一点

(伪代码)

class A;

class B : A;

class C : A, B;

...

A ac = (A)c;

...

B bc = (B)c;

这可能吗?

【问题讨论】:

标签: c# multiple-inheritance


【解决方案1】:

在这种特殊情况下您不需要多重继承:如果类 C 仅继承自 B,则类 C 的任何实例都可以同时转换为 B @ 987654325@;因为B 已经派生自AC 不需要再次派生自A

class A      { ... }

class B : A  { ... }

class C : B  { ... }

...

C c = new C();
B bc = (B)c;    // <-- will work just fine without multiple inheritance
A ac = (A)c;    // <-- ditto

(正如其他人已经说过的,如果您需要类似于多重继承的东西,请使用接口,因为一个类可以实现任意数量的接口。)

【讨论】:

  • Arggh... 我已经监督了显而易见的事情。感谢您的提示!问候
  • 嗯。一个问题仍然存在:我不能强迫 C 表现得像 A。B 增强了 A 并且不再提供简单的 A 功能(根据需要)。简单地说,我需要一个 C,它有时表现为 A,有时表现为 B,具体取决于上下文。
【解决方案2】:

没有。 C# 不支持类的多重继承。

一个类可以继承一个类,也可以实现多个接口。

【讨论】:

    【解决方案3】:

    这在 C# 中是不可能的,但是,你也应该考虑一下这是否是你真正想要的场景。

    C 真的是一个 A 和一个 B 吗?或者 C 一个 A 和一个 B。 如果后者为真,则应使用组合而不是继承。

    【讨论】:

    • 由于某些原因,我无法使用合成。试过了。问题:基类使用委托并在回调中提供对自身的引用。如果 C 包含 A 和 B,则回调包含对 A 和/或 B 的引用,而不是根据需要对 C 的引用。如果我从 A 和 B 继承 C,则可以确保这一点。接口是一个选项,已经使用它。
    【解决方案4】:

    您可以使用接口进行多重继承。

    【讨论】:

      【解决方案5】:

      C# 不支持多重继承,但正如其他人建议的那样,您可以使用多个接口。但是,即使使用接口,有时您也希望在同一个类中重用多个接口实现,这同样需要多重继承。

      为了解决这个问题(尽管它几乎是never needed),我提出了一种模拟多重继承方法,它使用了partial classesT4 Text Templates 的组合。这是一个小技巧,但比在许多派生类中复制/粘贴相同的接口实现要好。下面是一个简化的例子:

      IInterface.cs

      public interface IInterface
      {
          void Foo();
      }
      

      InterfaceImpl.cs

      public partial class InterfaceImpl : IInterface
      {
          public void Foo()
          {
              Console.WriteLine("Foo");
          }
      }
      

      BaseClass.cs

      using System;
      
      public class BaseClass
      {
          public void Bar()
          {
              Console.WriteLine("Bar");
          }
      }
      

      DerivedClassA.cs

      public partial class DerivedClassA : BaseClass, IInterface
      {
          public void FooBar()
          {
              this.Foo();
              this.Bar();
          }
      }
      

      DerivedClassAInterfaceImpl.tt

      <#@ template debug="false" hostspecific="true" language="C#" #>
      <#@ output extension=".cs" #>
      <# var codeText = System.IO.File.ReadAllText(this.Host.ResolvePath("InterfaceImpl.cs")).Replace("InterfaceImpl", "DerivedClassA"); #>
      <#= codeText #>
      

      DerivedClassB.cs

       public partial class DerivedClassB : BaseClass, IInterface
          {
              public void BarFoo()
              {
                  this.Bar();
                  this.Foo();
              }
          }
      

      DerivedClassBInterfaceImpl.tt

      <#@ template debug="false" hostspecific="true" language="C#" #>
      <#@ output extension=".cs" #>
      <# var codeText = System.IO.File.ReadAllText(this.Host.ResolvePath("InterfaceImpl.cs")).Replace("InterfaceImpl", "DerivedClassB"); #>
      <#= codeText #>
      

      这有点烦人,这需要为每个想要使用接口实现的派生类创建一个 tt 文件,但如果 InterfaceImpl.cs 超过几行代码,它仍然可以节省复制/粘贴代码。也可能只创建一个 tt 文件并指定所有派生部分类的名称并生成multiple files

      我在类似的问题here 中提到了这种方法。

      【讨论】:

        猜你喜欢
        • 2017-03-31
        • 2012-05-14
        • 2013-08-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-10
        相关资源
        最近更新 更多