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:
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:
domainAssembly.GetExportedTypes()
pour récupérer uniquement les types visibles publiquement (si c’est tout ce dont vous avez besoin). 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). && ! 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.