Bir Derlemede Belirli Bir C Tipinden Devralan tüm türleri bulma #


95

Belirli bir türden miras alan tüm türlerin bir koleksiyonunu nasıl elde edersiniz?

Yanıtlar:


154

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.


2
Teşekkürler! Bunu kullanmaya son verdim Teşekkürler - Bu genel statik Listeyi kullanmaya başladım <Type> GetAllSubclassesOf (Type baseType) {return Assembly.GetAssembly (baseType) .GetTypes (). Nerede (tür => type.IsSubclassOf (baseType)). Listeye(); }
aceinthehole

@ Downvoter burada. Yorumum kayboldu. Bir deliğin işaret ettiği gibi cevap yanlıştır. Kodun çalışmadığını bulana kadar as yorumunu kaçırdığım için doğru cevabı ekledim. Mutlu Noeller.
Tim Murphy

@Tim: Yanlış değil, biraz farklı. IsAssignableFromde çalışmalı. Özellikle benim versiyonum arayüzlerle de baş edebiliyor. Kodumu test ettin mi? Cevabım hangi durumda başarısız oluyor?
Jon Skeet

1
@Jon. Oldukça doğru yönteminiz arayüzleri ele alıyor. Ben bir VB programcısıyım, sınıfları miras alıyoruz ve arayüzler uyguluyoruz. Bu C # 'da farklı mı? Soruyorum çünkü sorduğum gibi, bir türü uygulamayan bir türü miras alan türler istiyor.
Tim Murphy

2
@Tim: C # 'da her ikisi için de sadece ":" kullanıyoruz ... ama genellikle arayüzleri bir türün miras hiyerarşisinin bir parçası olarak değerlendiririm.
Jon Skeet

27

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.


1

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.


1

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();
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.