Obtenir tous les types dérivés d’un type

Existe-t-il un meilleur moyen (plus performant ou plus agréable de code) pour trouver tous les types dérivés d’un type? Actuellement, j’utilise quelque chose comme:

  1. obtenir tous les types dans les assemblées utilisées
  2. vérifier mon type avec tous ces types s’il est ‘IsAssignable’

Je me demandais s’il y avait une meilleure façon de faire ça?

J’ai déjà utilisé cette méthode Linq pour obtenir tous les types héritant d’un type de base B:

var listOfBs = (from domainAssembly in AppDomain.CurrentDomain.GetAssemblies() from assemblyType in domainAssembly.GetTypes() where typeof(B).IsAssignableFrom(assemblyType) select assemblyType).ToArray(); 

EDIT : Comme cela semble toujours avoir plus de rep (donc plus de vues), permettez-moi d’append quelques détails supplémentaires:

  • Comme l’indique le lien mentionné ci-dessus, cette méthode utilise Reflection sur chaque appel. Ainsi, lorsque vous utilisez la méthode à plusieurs resockets pour le même type, vous pouvez probablement la rendre beaucoup plus efficace en la chargeant une fois.
  • Comme Anton le suggère, vous pourriez (micro) l’optimiser en utilisant domainAssembly.GetExportedTypes() pour récupérer uniquement les types visibles publiquement (si c’est tout ce dont vous avez besoin).
  • Comme Noldorin le mentionne, Type.IsAssignable obtiendra également le type original (non dérivé). ( Type.IsSubclassOf ne le fera pas, mais Type.IsSubclassOf ne fonctionnera pas si le type de base est une interface).
  • On peut vouloir / avoir besoin de vérifier une vraie classe: && ! assemblyType.IsAbstract && ! assemblyType.IsAbstract . (Notez que toutes les interfaces sont considérées abstraites, voir MSDN .)

Je suis sûr que la méthode que vous avez suggérée sera la plus simple pour trouver tous les types dérivés. Les classes parents ne stockent aucune information sur ce que sont leurs sous-classes (ce serait assez idiot si elles le faisaient), ce qui signifie qu’il ne faut pas chercher ici tous les types.

La seule recommandation est d’utiliser la méthode Type.IsSubclassOf au lieu de Type.IsAssignable afin de vérifier si un type particulier est dérivé d’un autre. Cependant, il y a peut-être une raison pour laquelle vous devez utiliser Type.IsAssignable (cela fonctionne avec des interfaces, par exemple).

La seule optimisation que vous pouvez en tirer est d’utiliser Assembly.GetExportedTypes() pour extraire uniquement les types visibles publiquement, si c’est le cas. En dehors de cela, il n’y a aucun moyen d’accélérer les choses. LINQ peut aider du côté de la lisibilité, mais pas du sharepoint vue des performances.

Vous pouvez faire un court-circuit pour éviter des appels inutiles à IsAssignableFrom qui, selon Reflector, est assez coûteux, en testant d’abord si le type en question est de la “classe” requirejse. C’est-à-dire que vous recherchez uniquement des classes, il est inutile de tester les énumérations ou les tableaux pour une “assignabilité”.

Je pense qu’il n’y a pas de meilleur ou de moyen direct.

Mieux: utilisez IsSubclassOf au lieu de IsAssignable .

Si vous utilisez baseType, vous devez rechercher un object System.Type et matchType contient un object System.Type avec le type de votre itération actuelle (via une boucle foreach ou autre):

Si vous voulez vérifier si le matchType est dérivé de la classe représentée par baseType, je l’utilise

 matchType.IsSubclassOf(baseType) 

Et si vous voulez vérifier si matchType implémente l’interface représentée par baseType, je l’utilise

 matchType.GetInterface(baseType.ToSsortingng(), false) != null 

Bien sûr, je stockerais baseType.ToSsortingng () en tant que variable globale afin de ne pas avoir à l’appeler tout le temps. Et puisque vous en auriez probablement besoin dans un contexte où vous avez beaucoup de types, vous pouvez également envisager d’utiliser la boucle System.Threading.Tasks.Parallel.ForEach pour parcourir tous vos types …

Si vous êtes simplement intéressé par la navigation, alors .NET Reflector a la capacité de le faire. Cependant, ce n’est pas quelque chose de vraiment faisable. Voulez-vous tous les types qui se trouvent dans les assemblys actuellement chargés? Assemblages référencés par l’assembly en cours d’exécution? Il existe de nombreuses manières d’obtenir une liste de types, et écrire quelque chose qui pourrait représenter (et fournir des options pour) serait un très gros coût avec des avantages relativement faibles.

Qu’essayez-vous de faire? Il y a probablement une meilleure façon (ou du moins plus efficace) de l’accomplir.