Tester si l'objet implémente l'interface


355

Quelle est la manière la plus simple de tester si un objet implémente une interface donnée en C #? (Réponse à cette question en Java )

Réponses:


570
if (object is IBlah)

ou

IBlah myTest = originalObject as IBlah

if (myTest != null)

85
+1 Le second est meilleur parce que vous finirez probablement par avoir besoin de lancer ensuite avec le premier vous donnant ainsi deux lancers ("est" puis un casting explicite). Avec la deuxième approche, vous ne lancez qu'une seule fois.
Andrew Hare

51
@Andrew: +1; Il est temps pour le lien vers le blog classique Double-Casting AntiPattern de Julian M Bucknall .
Jeroen Wiert Pluimers

1
L'optimisation ne vous fera probablement pas lancer deux fois dans le premier cas?
BuZz

1
@Joreen, ce lien manque un point si vous travaillez avec une structure que vous ne pouvez pas utiliser "as" car il ne contiendra pas de null qui est ce que le "as" essaie de retourner, dans ce cas, vous devez passer par un nullable classe comme int?, mais ce n'est pas un problème si vous ne travaillez qu'au niveau de l'interface car ce sont toujours des types de référence
MikeT

46
Depuis C # 6.0:if (object is IBlah iblah) { iblah.SomeMethod(); }
Knelis

224

L'utilisation des opérateurs isou asest la bonne façon si vous connaissez le type d'interface au moment de la compilation et avez une instance du type que vous testez. Quelque chose que personne d'autre ne semble avoir mentionné est Type.IsAssignableFrom:

if( typeof(IMyInterface).IsAssignableFrom(someOtherType) )
{
}

Je pense que c'est beaucoup plus net que de regarder à travers le tableau retourné par GetInterfaceset a l'avantage de travailler aussi pour les classes.


J'essaie de déterminer si un type implémente une instanciation d'IList. J'utilise "typeof (IList <>). IsAssignableFrom (someType)" mais cela ne fonctionne pas.
KeyboardDrummer

3
Vous feriez mieux de poser cette question dans une autre question. Si someType est le type des éléments de la liste, vous pourriez avoir besoin de typeof (IList <>). MakeGenericType (someType). Si someType est le type de liste, vous devez regarder Type.GetGenericArguments et Type.GetGenericTypeDefinition.
Andrew Kennan

Je l'utilise pour la vérification de type dans un système de plugins. Il peut être utilisé dans des situations où une instance de l'objet n'existe pas encore. Mais j'utilise à la fois ce style et celui de Robert en fonction de ce que je fais, j'ai donc voté dans les deux sens.
James

Il s'agit d'un commentaire plus ancien, mais pour répondre à la question de @ Steenreem, utilisez typeof(IList).IsAssignableFrom(someType)sans <>.
saluce

Cette méthode fonctionne même avec les opérateurs de conversion et si des convertisseurs de type sont impliqués
Harald Coppoolse

22

Par exemple:

if (obj is IMyInterface) {}

Pour la classe:

Vérifiez si typeof(MyClass).GetInterfaces()contient l'interface.


1
if (Array.IndexOf (typeof (MyClass) .GetInterfaces (), typeof (IMyInterface))! = -1) {...}
Constantin

2
ou: if (typeof (MyClass) .GetInterfaces (). Contains (typeof (IMyInterface))) {...}
Lance Fisher


16

Une variante de la réponse de @ AndrewKennan que j'ai fini par utiliser récemment pour les types obtenus lors de l'exécution:

if (serviceType.IsInstanceOfType(service))
{
    // 'service' does implement the 'serviceType' type
}

7

Ce message est une bonne réponse.

public interface IMyInterface {}

public class MyType : IMyInterface {}

Voici un exemple simple:

typeof(IMyInterface).IsAssignableFrom(typeof(MyType))

ou

typeof(MyType).GetInterfaces().Contains(typeof(IMyInterface))

3

En plus de tester en utilisant l'opérateur "is", vous pouvez décorer vos méthodes pour vous assurer que les variables qui lui sont passées implémentent une interface particulière, comme ceci:

public static void BubbleSort<T>(ref IList<T> unsorted_list) where T : IComparable
{
     //Some bubbly sorting
}

Je ne sais pas dans quelle version de .Net cela a été implémenté, donc cela peut ne pas fonctionner dans votre version.


2
.net 2.0 a ajouté des génériques.
Robert

C'est la seule vérification à la compilation dans ce fil, merci.
Dustin Malone

2

Ce qui a fonctionné pour moi, c'est:

Assert.IsNotNull(typeof (YourClass).GetInterfaces().SingleOrDefault(i => i == typeof (ISomeInterface)));


1

Récemment, j'ai essayé d'utiliser la réponse d'Andrew Kennan et cela n'a pas fonctionné pour moi pour une raison quelconque. Je l'ai utilisé à la place et cela a fonctionné (note: l'écriture de l'espace de noms peut être nécessaire).

if (typeof(someObject).GetInterface("MyNamespace.IMyInterface") != null)

2
Si vous finissez par emprunter cette voie, je ne suis pas un fan des cordes magiques, donc je changerais au minimum cela pour être typeof (IMyInterface) .Name au lieu de "MyNamespace.IMyInterface". Aide à en faire une preuve de refactorisation de nom en prime.
greyalien007

0

j'ai utilisé

Assert.IsTrue(myObject is ImyInterface);

pour un test dans mon test unitaire qui teste que myObject est un objet qui a implémenté mon interface ImyInterface.


-1

J'ai eu une situation où je passais une variable à une méthode et ne savais pas si ça allait être une interface ou un objet.

Les objectifs étaient les suivants:

  1. Si item est une interface, instanciez un objet basé sur cette interface avec l'interface étant un paramètre dans l'appel du constructeur.
  2. Si l'élément est un objet, retournez une valeur nulle, car le constructeur de mes appels attend une interface et je ne voulais pas que le code soit utilisé.

J'ai atteint cet objectif avec les éléments suivants:

    if(!typeof(T).IsClass)
    {
       // If your constructor needs arguments...
       object[] args = new object[] { my_constructor_param };
       return (T)Activator.CreateInstance(typeof(T), args, null);
    }
    else
       return default(T);

-12

Cela devrait fonctionner:

MyInstace.GetType().GetInterfaces();

Mais sympa aussi:

if (obj is IMyInterface)

Ou même (pas très élégant):

if (obj.GetType() == typeof(IMyInterface))

9
La vérification de l'égalité avec typeof (IMyInterface) échouera toujours. Voté.
Jay Bazuzi

Droite. Il n'y a aucune instance d'une interface.
Rauhotz
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.