Как вы получаете коллекцию всех типов, которые наследуются от определенного другого типа?
Как найти все типы в сборке, которые наследуют от определенного типа С#
Ответ 1
Что-то вроде:
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
Следующий метод получит набор типов, которые наследуют тип.
С#
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.
Ответ 3
Вы должны перечислить все типы и проверить для каждого, если он наследует тот, который вы ищете.
Некоторый код, такой как этот вопрос, может быть вам полезен.
Ответ 4
Рассмотрим использование этого метода (написанного для 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();
}