Como você obtém uma coleção de todos os tipos que herdam de um outro tipo específico?
Como você obtém uma coleção de todos os tipos que herdam de um outro tipo específico?
Respostas:
Algo como:
public IEnumerable<Type> FindDerivedTypes(Assembly assembly, Type baseType)
{
return assembly.GetTypes().Where(t => baseType.IsAssignableFrom(t));
}
Se você precisa lidar com genéricos, fica um pouco mais complicado (por exemplo, passar o List<>
tipo aberto, mas esperando receber de volta um tipo derivado de List<int>
). Caso contrário, é simples :)
Se você deseja excluir o próprio tipo, pode fazer isso com bastante facilidade:
public IEnumerable<Type> FindDerivedTypes(Assembly assembly, Type baseType)
{
return assembly.GetTypes().Where(t => t != baseType &&
baseType.IsAssignableFrom(t));
}
Observe que isso também permitirá que você especifique uma interface e encontre todos os tipos que a implementam, em vez de apenas trabalhar com classes como Type.IsSubclassOf
faz.
IsAssignableFrom
deve funcionar também. Em particular, minha versão lida com interfaces também. Você testou meu código? Em que caso minha resposta falha?
O método a seguir obterá uma coleção de tipos que herdam um tipo.
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
Se você precisa incluir tipos que implementam uma interface, veja a resposta de @Jon Skeet.
Você tem que enumerar todos os tipos e verificar se cada um herda o que você está procurando.
Algum código como o desta questão pode ser útil para você.
Considere usar este método (escrito para um 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();
}