Как найти все типы в сборке, которые наследуются от определенного типа C #


Ответы:


152

Что-то типа:

public IEnumerable<Type> FindDerivedTypes(Assembly assembly, Type baseType)
{
    return assembly.GetTypes().Where(t => baseType.IsAssignableFrom(t));
}

Если вам нужно обрабатывать дженерики, это становится несколько сложнее (например, передача открытого List<>типа, но ожидание возврата типа, производного от List<int>). В остальном все просто :)

Если вы хотите исключить сам тип, вы можете сделать это достаточно легко:

public IEnumerable<Type> FindDerivedTypes(Assembly assembly, Type baseType)
{
    return assembly.GetTypes().Where(t => t != baseType && 
                                          baseType.IsAssignableFrom(t));
}

Обратите внимание, что это также позволит вам указать интерфейс и найти все типы, которые его реализуют, а не просто работать с классами, как это Type.IsSubclassOfделает.


2
Благодарность! В итоге я использовал это Спасибо - я использовал этот общедоступный статический List <Type> GetAllSubclassesOf (Type baseType) {return Assembly.GetAssembly (baseType) .GetTypes (). Где (type => type.IsSubclassOf (baseType)). Составлять список(); }
aceinthehole

@Downvoter здесь. Мой комментарий пропал. Как указывает aceinthehole, ответ неверен. Я добавил правильный ответ, так как пропустил комментарий тузов, пока не обнаружил, что код не работает. С Рождеством.
Тим Мерфи

@ Тим: Это не неправильно, это немного другое. IsAssignableFromтоже должно работать. В частности, моя версия тоже справляется с интерфейсами. Вы тестировали мой код? В каком случае я не могу ответить?
Джон Скит,

1
@Jon. Совершенно верно, ваш метод обрабатывает интерфейсы. Я программист на VB, мы наследуем классы и реализуем интерфейсы. Это другое в C #? Я спрашиваю, потому что вопрос, как я и требовал, хочет, чтобы типы, наследующие тип, не реализуют тип.
Тим Мерфи

2
@Tim: В C # мы просто используем ":" для обоих ... но я бы обычно рассматривал интерфейсы как часть иерархии наследования типа.
Джон Скит,

27

Следующий метод получит коллекцию типов, наследующих тип.

C #

public IEnumerable<Type> FindSubClassesOf<TBaseType>()
{   
    var baseType = typeof(TBaseType);
    var assembly = baseType.Assembly;

    return assembly.GetTypes().Where(t => t.IsSubclassOf(baseType));
}

VB.NET

Public Function FindSubClasses(Of TBaseType)() As IEnumerable(Of Type)

    Dim baseType = GetType(TBaseType)
    Dim assembly = baseType.Assembly

    Return From t In assembly.GetTypes() 
           Where t.IsSubClassOf(baseType) 
           Select t

End Function

Если вам нужно включить типы, реализующие интерфейс, см. Ответ @Jon Skeet.


1

Вы должны перечислить все типы и проверить для каждого, наследует ли он тот, который вы ищете.

Некоторые коды, подобные приведенному в этом вопросе, могут быть вам полезны.


1

Рассмотрите возможность использования этого метода (написанного для PCL):

public IEnumerable<Type> FindDerivedTypes( Assembly assembly, Type baseType )
{
        TypeInfo baseTypeInfo = baseType.GetTypeInfo();
        bool isClass = baseTypeInfo.IsClass, isInterface = baseTypeInfo.IsInterface;

        return
            from type in assembly.DefinedTypes
            where isClass ? type.IsSubclassOf( baseType ) :
                  isInterface ? type.ImplementedInterfaces.Contains( baseTypeInfo.AsType() ) : false
            select type.AsType();
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.