55 votes

Savoir si un type implémente une interface générique

Disons que j'ai un type, MyType. Je veux faire ce qui suit:

  1. Savoir si MyType implémente l'interface IList, pour certains T.
  2. Si la réponse à (1) est oui, ce T est.

Il semble que la façon de le faire est GetInterface(), mais qui permet une recherche par un nom spécifique. Est-il un moyen de la recherche pour "toutes les interfaces qui sont de la forme IList" (Si possible, il woudl également être utile si cela a fonctionné si l'interface était un subinterface de IList.)

Connexes: Comment faire pour déterminer si un type implémente un générique type d'interface

84voto

Anton Tykhyy Points 12680
 // this conditional is necessary if myType can be an interface,
// because an interface doesn't implement itself: for example,
// typeof (IList<int>).GetInterfaces () does not contain IList<int>!
if (myType.IsInterface && myType.IsGenericType && 
    myType.GetGenericTypeDefinition () == typeof (IList<>))
    return myType.GetGenericArguments ()[0] ;

foreach (var i in myType.GetInterfaces ())
    if (i.IsGenericType && i.GetGenericTypeDefinition () == typeof (IList<>))
        return i.GetGenericArguments ()[0] ;
 

Edit: Même si myType implémente IDerivedFromList<> mais pas directement IList<> , IList<> apparaîtra dans le tableau renvoyé par GetInterfaces() .

Mise à jour: ajout d'une vérification du cas d'extrémité où myType est l'interface générique en question.

11voto

casperOne Points 49736

L'utilisation de la réflexion (et certains LINQ), vous pouvez facilement faire cela:

public static IEnumerable<Type> GetIListTypeParameters(Type type)
{
    // Query.
    return
        from interfaceType in type.GetInterfaces()
        where interfaceType.IsGenericType
        let baseInterface = interfaceType.GetGenericTypeDefinition()
        where baseInterface == typeof(IList<>)
        select interfaceType.GetGenericArguments().First();
}

Tout d'abord, vous obtenez les interfaces sur le type et le filtrage seulement pour ceux qui sont d'un type générique.

Ensuite, vous obtenez le générique de la définition de type pour ces types d'interface, et de voir si c'est la même que IList<>.

À partir de là, c'est un moyen simple d'obtenir des arguments génériques de l'interface d'origine.

Rappelez-vous, un type peut avoir plusieurs IList<T> des implémentations, c'est pourquoi l' IEnumerable<Type> est retourné.

4voto

user989279 Points 21
    public static bool Implements<I>(this Type type) where I : class
    {
         if (!typeof(I).IsInterface)
         {
             throw new ArgumentException("Only interfaces can be 'implemented'.");
         }

         return typeof(I).IsAssignableFrom(type);
    }

1voto

GenericProgrammer Points 131

En tant qu'extension de méthode d'assistance

 public static bool Implements<I>(this Type type, I @interface) where I : class  
{
    if(((@interface as Type)==null) || !(@interface as Type).IsInterface)
        throw new ArgumentException("Only interfaces can be 'implemented'.");

    return (@interface as Type).IsAssignableFrom(type);
}
 

exemple d'utilisation:

 var testObject = new Dictionary<int, object>();
result = testObject.GetType().Implements(typeof(IDictionary<int, object>)); // true!
 

0voto

Chris Ballance Points 17329
 Type[] typeArray2 = c.GetInterfaces();
for (int num2 = 0; num2 < typeArray2.Length; num2++)
{
     if (this == typeArray2[num2])
     {
          return true;
     }
}
 

- http://www.hanselman.com/blog/DoesATypeImplementAnInterface.aspx

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X