Jak uzyskać kolekcję wszystkich typów, które dziedziczą z określonego innego typu?
Jak uzyskać kolekcję wszystkich typów, które dziedziczą z określonego innego typu?
Odpowiedzi:
Coś jak:
public IEnumerable<Type> FindDerivedTypes(Assembly assembly, Type baseType)
{
return assembly.GetTypes().Where(t => baseType.IsAssignableFrom(t));
}
Jeśli potrzebujesz obsługiwać List<>
typy generyczne, staje się to nieco trudniejsze (np. Przekazanie typu otwartego, ale oczekiwanie na powrót typu, który pochodzi z List<int>
). W przeciwnym razie jest to proste :)
Jeśli chcesz wykluczyć sam typ, możesz to łatwo zrobić:
public IEnumerable<Type> FindDerivedTypes(Assembly assembly, Type baseType)
{
return assembly.GetTypes().Where(t => t != baseType &&
baseType.IsAssignableFrom(t));
}
Zauważ, że pozwoli ci to również określić interfejs i znaleźć wszystkie typy, które go implementują, zamiast tylko pracować z klasami, jak to Type.IsSubclassOf
ma miejsce.
IsAssignableFrom
powinno również działać. W szczególności moja wersja radzi sobie również z interfejsami. Czy przetestowałeś mój kod? W jakim przypadku moja odpowiedź kończy się niepowodzeniem?
Poniższa metoda spowoduje pobranie kolekcji typów, które dziedziczą typ.
DO#
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
Jeśli potrzebujesz dołączyć typy, które implementują interfejs, zobacz odpowiedź @Jon Skeet.
Musisz wyliczyć wszystkie typy i sprawdzić, czy dziedziczy on ten, którego szukasz.
Niektóre kody, takie jak w tym pytaniu, mogą być przydatne.
Rozważ użycie tej metody (napisanej dla języka 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();
}