Список типов, реализующих интерфейс или базовый класс

Как мне определить список типов (List<Type>), где я хочу ограничить типы в этом списке типами, которые реализуют интерфейс или базовый класс?

Для очень упрощенного примера того, чего я хочу достичь, у меня есть абстрактный класс Foo со многими различными дочерними классами FooA, FooB, FooC, FooD и т. д. Затем у меня есть еще один класс BarAD со списком разрешенных Foo типов (FooA и FooD) для некоторых операций. Тогда произойдет что-то вроде следующего:

public class BarAD
{
    private List<Type> fooTypes;

    public BarAD()
    {
        fooTypes = new List<Type>() { typeof(FooA), typeof(FooD) };
    }

    public void Execute(Foo obj)
    {
        foreach (var fooType in fooTypes)
        {
            if (obj is fooType)
                obj.DoSomething();
        }
    }
}

Как это сейчас работает, я могу использовать любой тип в моем списке. Какой-то метод может добавить String или Integer в качестве типов в список, и код будет компилироваться и работать нормально, что немного усложняет мою жизнь в будущем. Что возвращает меня к вопросу: каким-либо образом ограничить мой List<Type>, чтобы принимать только типы, которые являются дочерними элементами класса Foo?


person Sushi Yeti Dev    schedule 18.11.2019    source источник
comment
Вы не можете ограничить это во время компиляции. Type — это класс .NET, и он применим ко всем типам. Вы можете ограничить это во время выполнения, используя отражение. Проверьте здесь   -  person Chetan Ranpariya    schedule 18.11.2019
comment
Вы ищете IsAssignableFrom в типе Type.   -  person Enigmativity    schedule 18.11.2019
comment
@Enigmativity Как бы я использовал это, чтобы делать то, что мне нужно?   -  person Sushi Yeti Dev    schedule 19.11.2019
comment
@SushiYetiDev - Что-то вроде var derived = this.GetType().Assembly.GetTypes().Where(x => typeof(Foo).IsAssignableFrom(x)).ToList();.   -  person Enigmativity    schedule 19.11.2019


Ответы (1)


Возможно, вы можете использовать общее ограничение.

public class BarAD
{
    private List<Type> Types = new List<Type>();

    public void Add<T>() where T : Foo
    {
        Types.Add( typeof( T ) );
    }
}

static void Main( string[] args )
{
    BarAD bar = new BarAD();
    bar.Add<FooA>();
    bar.Add<FooD>();
}

Хотя мне кажется это несколько странным. Обычно я хотел бы использовать полиморфизм вместо типов.

person Leisen Chang    schedule 18.11.2019
comment
Я согласен с ощущением. Я также нахожу это очень странным, но я не вижу лучшего способа достичь того, что я хочу сделать. Причина этого в том, что это часть процедурного алгоритма, и нам нужно иметь возможность сохранять его результаты. Я учту ваше предложение и попробую его, но я не думаю, что он сможет делать то, что я хочу. - person Sushi Yeti Dev; 18.11.2019
comment
Это не отвечает на вопрос: есть ли способ ограничить мой List<Type> только приемом типов, которые являются дочерними элементами класса Foo? - person Enigmativity; 18.11.2019