Belirli bir türden miras alan tüm türlerin bir koleksiyonunu nasıl elde edersiniz?
Belirli bir türden miras alan tüm türlerin bir koleksiyonunu nasıl elde edersiniz?
Yanıtlar:
Gibi bir şey:
public IEnumerable<Type> FindDerivedTypes(Assembly assembly, Type baseType)
{
return assembly.GetTypes().Where(t => baseType.IsAssignableFrom(t));
}
Eğer jenerikleri işlemeniz gerekiyorsa, bu biraz daha karmaşık hale gelir (örneğin, açık List<>
tipte geçmek, ancak türetilen bir türü geri almayı beklemek List<int>
). Aksi takdirde, yine de basit :)
Yazının kendisini hariç tutmak istiyorsanız, bunu yeterince kolay bir şekilde yapabilirsiniz:
public IEnumerable<Type> FindDerivedTypes(Assembly assembly, Type baseType)
{
return assembly.GetTypes().Where(t => t != baseType &&
baseType.IsAssignableFrom(t));
}
Bunun aynı zamanda sınıflarla olduğu gibi çalışmak yerine bir arabirim belirlemenize ve onu uygulayan tüm türleri bulmanıza izin vereceğini unutmayın Type.IsSubclassOf
.
IsAssignableFrom
de çalışmalı. Özellikle benim versiyonum arayüzlerle de baş edebiliyor. Kodumu test ettin mi? Cevabım hangi durumda başarısız oluyor?
Aşağıdaki yöntem, bir türü miras alan türlerin bir koleksiyonunu alacaktır.
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
Bir arabirim uygulayan türler eklemeniz gerekiyorsa, @Jon Skeet'in cevabına bakın.
Tüm türleri numaralandırmanız ve aradığınız türü miras alıp almadığını kontrol etmeniz gerekir.
Bu sorudaki gibi bazı kodlar sizin için yararlı olabilir.
Bu yöntemi kullanmayı düşünün (bir PCL için yazılmıştır):
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();
}