C # - Наследование и интерфейсы - PullRequest
0 голосов
/ 05 октября 2018

Извините за плохой заголовок, но я не знаю, как правильно обозначить это.

Позвольте следующие интерфейсы:

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.Так что это выглядит немного грязно и может вызвать у меня проблемы, которых я пока не вижу.

У меня есть другой способ достичь того, что мне нужно сделать, кроме двух упомянутых выше возможностей?Спасибо!

1 Ответ

0 голосов
/ 05 октября 2018

Как насчет класса с неявными операторами, чтобы иметь возможность конструировать и возвращать все нужные типы.

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];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...