Come trovare tutti i tipi in un assembly che ereditano da un tipo specifico C #


Risposte:


150

Qualcosa di simile a:

public IEnumerable<Type> FindDerivedTypes(Assembly assembly, Type baseType)
{
    return assembly.GetTypes().Where(t => baseType.IsAssignableFrom(t));
}

Se hai bisogno di gestire i generici, diventa un po 'più complicato (ad esempio, passare il List<>tipo aperto ma aspettarti di recuperare un tipo che deriva da List<int>). Altrimenti è semplice però :)

Se vuoi escludere il tipo stesso, puoi farlo abbastanza facilmente:

public IEnumerable<Type> FindDerivedTypes(Assembly assembly, Type baseType)
{
    return assembly.GetTypes().Where(t => t != baseType && 
                                          baseType.IsAssignableFrom(t));
}

Nota che questo ti permetterà anche di specificare un'interfaccia e trovare tutti i tipi che la implementano, invece di lavorare solo con le classi come Type.IsSubclassOffa.


2
Grazie! Ho finito per usare questo Grazie - ho finito per usare questo List <Type> GetAllSubclassesOf (Type baseType) {return Assembly.GetAssembly (baseType) .GetTypes () statico pubblico. Dove (type => type.IsSubclassOf (baseType)). Elencare(); }
aceinthehole il

@Downvoter qui. Il mio commento è scomparso. Come indicato da asso nel buco, la risposta non è corretta. Ho aggiunto la risposta corretta poiché ho perso il commento degli assi finché non ho scoperto che il codice non funzionava. Buon Natale.
Tim Murphy

@ Tim: non è corretto, è leggermente diverso. IsAssignableFromdovrebbe funzionare anche. In particolare, la mia versione gestisce anche le interfacce. Hai testato il mio codice? In quale caso la mia risposta non riesce?
Jon Skeet

1
@ Jon. Giustamente il tuo metodo gestisce le interfacce. Sono un programmatore VB, ereditiamo classi e implementiamo interfacce. È diverso in C #? Lo chiedo perché la domanda, come ho richiesto, vuole che i tipi che ereditano un tipo non implementino un tipo.
Tim Murphy

2
@ Tim: In C # usiamo solo ":" per entrambi ... ma generalmente considererei le interfacce come parte della gerarchia di ereditarietà di un tipo.
Jon Skeet

27

Il metodo seguente otterrà una raccolta di tipi che ereditano 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

Se è necessario includere tipi che implementano un'interfaccia, vedere la risposta di @Jon Skeet.


1

Devi enumerare tutti i tipi e verificare per ognuno se eredita quello che stai cercando.

Un codice come quello in questa domanda potrebbe esserti utile.


1

Considera l'utilizzo di questo metodo (scritto per un 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();
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.