Извините за плохой титул, но я не знал, как правильно это назвать.
Пусть следующие интерфейсы:
interface IFoo
{
}
interface IBar
{
}
И следующие классы:
class Base
{
}
class Derived1 : Base, IFoo, IBar
{
}
class Derived2 : Base, IFoo, IBar
{
}
Мне нужно иметь общий тип для Derived1
и Derived2
который имеет все функции Base
, IFoo
и IBar
. так что я могу иметь экземпляры Derived1
и Derived2
в одной коллекции и иметь доступ к функциям Base
, IFoo
и IBar
не выполняя какую-либо черную магию рефлексии.
Если Base
был интерфейсом, мне просто нужно было бы создать интерфейс, требующий реализации Base
, IFoo
и IBar
, но это не так.
Я также не хочу иметь промежуточное наследование между Derived1
/Derived2
и Base
:
class Intermediate : Base, IFoo, IBar
{
}
class Derived1 : Intermediate
{
}
class Derived2 : Intermediate
{
}
Потому что я в контексте Единства, и наследования следует избегать там больше, чем где бы то ни было.
Также я не могу изменить Base
.
Я думал о наличии интерфейса IBase
который требует всех функций Base
и имеет "промежуточный" интерфейс, требующий его реализации, то есть:
interface IIntermediate : IBase, IFoo, IBar
{
}
class Derived1 : Base, IIntermediate
{
}
class Derived2 : Base, IIntermediate
{
}
Но мне пришлось бы скопировать все функции Base
(и его родителей) в IBase
а IBase
также не была бы Base
. Так что выглядит немного грязно и может вызвать у меня проблемы, которые я пока не вижу.
У меня есть другой способ добиться того, что мне нужно сделать, кроме двух упомянутых выше возможностей? Спасибо !
Как насчет того, чтобы класс с неявными операторами мог построить и вернуть все нужные типы.
class MyBase : IFoo, IBar
{
Base innerValue;
public static implicit operator Base(MyBase value)
{
return value.innerValue;
}
public static implicit operator MyBase(Derived1 value)
{
return new MyBase(value);
}
public static implicit operator MyBase(Derived2 value)
{
return new MyBase(value);
}
public MyBase(Derived1 value)
{
innerValue = value;
}
public MyBase(Derived2 value)
{
innerValue = value;
}
// Implement IFoo and IBar based on innerValue calls
}
Это позволит вам создать такой массив:
MyBase[] myArray = new MyBase[] {new Derived1(), new Derived2()};
И вы все равно можете рассматривать каждый экземпляр как базу:
Base B1 = myArray[0];
Derived1
и Derived2
прежнему будут наследоваться от Base, как вы и кодировали. Это то, что позволяет операторам MyBase автоматически конвертировать из Derived1
в Base
в конструкторах MyBase
.
Base
, неясно, почему дополнительный уровень наследования был бы нежелателен.Base
?