c # множественное наследование - PullRequest
7 голосов
/ 13 февраля 2010

Я хотел бы добиться этого в C #

(псевдокод)

class A;

class B : A;

class C : A, B;

...

A ac = (A)c;

...

B bc = (B)c;

Возможно ли это?

Ответы [ 5 ]

9 голосов
/ 13 февраля 2010

Вам не нужно множественное наследование в этом конкретном случае: если класс C наследует только от B, любой экземпляр класса C может быть приведен к B и * 1007. *; поскольку B уже получено из A, C не нужно снова выводить из 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

(Как уже говорили другие, если вам нужно что-то похожее на множественное наследование, используйте интерфейсы, поскольку класс может реализовать столько их, сколько вы хотите.)

3 голосов
/ 13 февраля 2010

Нет. C # не поддерживает множественное наследование классов.

Класс может наследоваться от одного класса, а также может реализовывать несколько интерфейсов.

2 голосов
/ 13 февраля 2010

Это невозможно в C #, но вы также должны подумать, действительно ли это тот сценарий, который вам нужен.

Является ли C действительно A и B ? Или C имеет , A и B . Если последнее верно, вы должны использовать композицию вместо наследования.

0 голосов
/ 15 января 2012

C # не поддерживает множественное наследование, но, как другие предложили, вы можете использовать несколько интерфейсов. Однако даже с интерфейсами иногда требуется повторно использовать несколько реализаций интерфейса в одном классе, что опять-таки потребует множественного наследования.

Чтобы обойти это (хотя это почти никогда не нужно ), я придумала подход имитированного множественного наследования, использующий комбинацию частичных классов и T4 Text Шаблоны . Это небольшой взлом, но это лучше, чем копировать / вставлять одну и ту же реализацию интерфейса во многих производных классах. Ниже приведен упрощенный пример:

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 и указать имя всех производных частичных классов и сгенерировать несколько файлов .

Я упомянул этот подход в аналогичном вопросе здесь .

0 голосов
/ 13 февраля 2010

вы можете использовать интерфейсы для множественного наследования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...