web-dev-qa-db-fra.com

Comment trouver tous les types dans un assembly qui héritent d'un type spécifique C #

Comment obtenir une collection de tous les types qui héritent d'un autre type spécifique?

88
aceinthehole

Quelque chose comme:

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

Si vous avez besoin de manipuler des génériques, cela devient un peu plus délicat (par exemple, passer dans le _ List<> type mais en attendant de récupérer un type dérivé de List<int>). Sinon, c'est simple :)

Si vous souhaitez exclure le type lui-même, vous pouvez le faire assez facilement:

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

Notez que cela vous permettra également de spécifier une interface et de trouver tous les types qui l'implémentent, plutôt que de simplement travailler avec des classes comme Type.IsSubclassOf Est-ce que.

143
Jon Skeet

La méthode suivante obtient une collection de types qui héritent d'un type.

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

Si vous devez inclure des types qui implémentent une interface, consultez la réponse de @Jon Skeet.

26
Tim Murphy

Pensez à utiliser cette méthode (écrite pour 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();
}
1
HappyNomad

Vous devez énumérer tous les types et vérifier s'ils héritent de celui que vous recherchez.

Un code comme celui de cette question peut vous être utile.

1
Thomas Danecker