¿Cómo se obtiene una colección de todos los tipos que heredan de otro tipo específico?
¿Cómo se obtiene una colección de todos los tipos que heredan de otro tipo específico?
Respuestas:
Algo como:
public IEnumerable<Type> FindDerivedTypes(Assembly assembly, Type baseType)
{
return assembly.GetTypes().Where(t => baseType.IsAssignableFrom(t));
}
Si necesita manejar genéricos, eso se vuelve algo más complicado (por ejemplo, pasar el List<>
tipo abierto pero esperar obtener un tipo derivado de List<int>
). De lo contrario, es simple aunque :)
Si desea excluir el tipo en sí, puede hacerlo con bastante facilidad:
public IEnumerable<Type> FindDerivedTypes(Assembly assembly, Type baseType)
{
return assembly.GetTypes().Where(t => t != baseType &&
baseType.IsAssignableFrom(t));
}
Tenga en cuenta que esto también le permitirá especificar una interfaz y encontrar todos los tipos que la implementan, en lugar de simplemente trabajar con clases como lo Type.IsSubclassOf
hace.
IsAssignableFrom
debería funcionar también. En particular, mi versión también se adapta a las interfaces. ¿Probaste mi código? ¿En qué caso falla mi respuesta?
El siguiente método obtendrá una colección de tipos que heredan un 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
Si necesita incluir tipos que implementan una interfaz, consulte la respuesta de @Jon Skeet.
Tienes que enumerar todos los tipos y comprobar cada uno si hereda el que estás buscando.
Algún código como el de esta pregunta puede resultarle útil.
Considere usar este método (escrito para una 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();
}