Est -ce que la réflexion en C#
offre un moyen de déterminer si certains étant donné les System.Type
modèles de type une interface?
public interface IMyInterface {}
public class MyType : IMyInterface {}
// should yield 'true'
typeof(MyType)./* ????? */MODELS_INTERFACE(IMyInterface);
c#
reflection
interface
Yippie-Ki-Yay
la source
la source
IsAssignableFrom
arrière. J'irai avecGetInterfaces
maintenant: pIsAssignableFrom(t1)
variante est environ 3 fois plus rapide que l'GetInterfaces().Contains(t2)
homologue de mon code.typeof(MyType).GetInterface(nameof(IMyInterface)) != null
améliorer la sécurité des types et la refactorisation.Utilisation
Type.IsAssignableFrom
:la source
ou
la source
someclass is IMyInterface
car cela n'implique pas du tout le coût de la réflexion. Donc, même si ce n'est pas faux, ce n'est pas un moyen idéal de le faire.is
vérifie dans les deux sens de la hiérarchie d'héritage alors queIsAssignableFrom
ne vérifie que vers le haut. De plus, si vous avez une instance d'un objet, vous devez appelerIsInstanceOfType
(qui ne regarde que vers le haut).Je pense que c'est la version correcte, pour trois raisons:
la source
Je viens de faire:
J'aurais aimé pouvoir dire
where I : interface
, mais ceinterface
n'est pas une option de contrainte de paramètre générique.class
est aussi proche que possible.Usage:
Je viens de le dire
Implements
parce que c'est plus intuitif. Je suis toujoursIsAssignableFrom
retourné.la source
return typeof(I).IsInterface && typeof(I).IsAssignableFrom(source);
pour retourner false sur toute utilisation «incorrecte» de la méthode, c'est-à-dire; en l'utilisant avec un type de classe au lieu d'un type d'interface, lève également une exception si le paramètre-type n'est pas une interface. Bien que vous puissiez affirmer qu'une classe dérivée «implémente» son parent ...Modifier la réponse de Jeff pour des performances optimales (grâce au test de performance de Pierre Arnaud):
Pour trouver tous les types qui implémentent une interface dans un domaine donné
Assembly
:la source
Comme quelqu'un d'autre l'a déjà mentionné: Benjamin 10 avril 13 à 22:21 "
Eh bien, une autre solution consiste simplement à créer une méthode d'extension courte qui remplit, dans une certaine mesure, la façon de penser "la plus habituelle" (et il a été convenu que c'est un très petit choix personnel pour le rendre légèrement "plus naturel" en fonction de ses préférences). ):
Et pourquoi ne pas aller un peu plus générique (eh bien je ne sais pas si c'est vraiment si intéressant, eh bien je suppose que je passe juste une autre pincée de sucre de 'syntaxe'):
Je pense que cela pourrait être beaucoup plus naturel de cette façon, mais encore une fois, juste une question d'opinions très personnelles:
la source
Boolean
=>bool
(je ne sais pas pourquoi j'avais l'habitude d'avoir des règles de codage "fantaisistes" strictes quand j'étais plus jeune).Si vous avez un type ou une instance, vous pouvez facilement vérifier s'ils prennent en charge une interface spécifique.
Pour tester si un objet implémente une certaine interface:
Pour tester si un type implémente une certaine interface:
Si vous avez un objet générique et que vous souhaitez effectuer un cast ainsi qu'une vérification si l'interface vers laquelle vous castez est implémentée, le code est:
la source
IsAssignableFrom
est désormais déplacé versTypeInfo
:la source
Quiconque le recherche peut trouver utile la méthode d'extension suivante:
tests xunit:
la source
qu'en est-il de
?
la source
Qu'en est-il de
la source
Une bonne réponse est
cependant,
peut renvoyer un résultat incorrect, comme le montre le code suivant avec chaîne et IConvertible:
Résultats:
la source
IsAssignableFrom
. Tout comme Benjamin et Ehouarn le préviennent.Notez que si vous avez une interface générique,
IMyInterface<T>
cela retournera toujoursfalse
:Cela ne fonctionne pas non plus:
Cependant, si
MyType
implémenteIMyInterface<MyType>
cela fonctionne et retournetrue
:Cependant, vous ne connaîtrez probablement pas le paramètre de type
T
lors de l'exécution . Une solution quelque peu hacky est:La solution de Jeff est un peu moins hacky:
Voici une méthode d'extension
Type
qui fonctionne dans tous les cas:(Notez que ce qui précède utilise linq, qui est probablement plus lent qu'une boucle.)
Vous pouvez alors faire:
la source