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.