Я хотел бы добиться этого в C#C# множественное наследование
(псевдокод)
class A;
class B : A;
class C : A, B;
...
A ac = (A)c;
...
B bc = (B)c;
Возможно ли это?
Я хотел бы добиться этого в C#C# множественное наследование
(псевдокод)
class A;
class B : A;
class C : A, B;
...
A ac = (A)c;
...
B bc = (B)c;
Возможно ли это?
№ C# не поддерживает множественное наследование классов.
Класс может наследовать от одного класса и может также реализовывать несколько интерфейсов.
@stakx: хороший улов. Исправленный. –
Вы можете использовать интерфейсы для множественного наследования.
В C# это невозможно, но вам также следует подумать, действительно ли это тот сценарий, который вы действительно хотите.
ЯвляетсяC действительно и B? Или Cимеет a A и a B. Если последнее верно, вы должны использовать композицию вместо наследования.
Я не могу использовать композицию по некоторым причинам. Пробовал это. Проблема. Базовые классы используют делегаты и предоставляют ссылки на себя в обратном вызове. Если C включает A и B, обратные вызовы содержат ссылки на A и/или B, а не на C, как требуется. Это обеспечивается, если я наследую C от A и B. Интерфейсы - это опция, используйте ее уже. – neil
Вам не нужно множественное наследование в данном случае: если класс C
наследует только от B
, любой экземпляр класса C
может быть брошено на оба B
иA
; поскольку 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
(Как и другие уже сказал, если вам нужно что-то похожее на множественное наследование, использование интерфейсов, так как класс может реализовать как многие из них, как вы хотите.)
Аргх ... Я наблюдал за очевидным. Спасибо за подсказку! С уважением – neil
Хммм. Остается одна проблема: я не могу заставить C вести себя как A. B усиливает A и больше не предоставляет простые функциональные возможности (по мере необходимости). Проще говоря, мне нужен C, который иногда ведет себя как A, а иногда и B, в зависимости от контекста. – neil
'C' должен вести себя как' A', если вы получите доступ к нему через 'ac'; Аналогично, 'C' должен вести себя как' B', если вы получите доступ к нему через 'bc'. Конечно, если у вас есть виртуальные методы, во всех этих случаях будут вызываться переопределенные версии. – stakx
C# не поддерживает множественное наследование, но, как предложили другие, вы можете использовать несколько интерфейсов. Однако даже с интерфейсами иногда вы хотите повторно использовать несколько реализаций интерфейса в одном классе, что опять-таки потребует многократного наследования.
Чтобы обойти это (хотя это почти never needed), я придумал метод имитации множественного наследования с использованием комбинации partial classes и T4 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.тт
<#@ 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.
Нет, проверьте: http://stackoverflow.com/questions/191691/ http://stackoverflow.com/questions/995255/ –
http://stackoverflow.com/questions/2846752/am-i -trying-to-implement-multiple-inheritance-how-can-i-do-this и http://stackoverflow.com/questions/2456154/does-c-support-multiple-inheritance – Russell