Averiguar si un tipo implementa una interfaz genérica

Digamos que tengo un tipo, MyType. Quiero hacer lo siguiente:

  1. Averigüe si MyType implementa la interfaz IList, para algunos T.
  2. Si la respuesta a (1) es sí, averigüe qué es T.

Parece que la forma de hacerlo es GetInterface (), pero eso solo le permite buscar por un nombre específico. ¿Hay alguna manera de buscar “todas las interfaces que son de la forma IList” (si es posible, también sería útil si funcionó si la interfaz era una subinterfaz de IList).

Relacionado: Cómo determinar si un tipo implementa un tipo de interfaz genérico específico

// this conditional is necessary if myType can be an interface, // because an interface doesn't implement itself: for example, // typeof (IList).GetInterfaces () does not contain IList! 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] ; 

Editar: Incluso si myType implementa IDerivedFromList<> pero no directamente IList<> , IList<> aparecerá en la matriz devuelta por GetInterfaces() .

Actualización: se agregó una myType para el caso límite donde myType es la interfaz genérica en cuestión.

Usando la reflexión (y algunos LINQ) puedes hacer esto fácilmente:

 public static IEnumerable 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(); } 

En primer lugar, obtendrá las interfaces del tipo y el filtrado solo para aquellas que son de tipo genérico.

Luego, obtienes la definición de tipo genérico para esos tipos de interfaz, y ves si es lo mismo que IList<> .

A partir de ahí, es una simple cuestión de obtener los argumentos generics para la interfaz original.

Recuerde, un tipo puede tener múltiples implementaciones IList , razón por la cual se IEnumerable .

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

Como una extensión de método auxiliar

 public static bool Implements(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); } 

uso de ejemplo:

 var testObject = new Dictionary(); result = testObject.GetType().Implements(typeof(IDictionary)); // true! 

Utilizando la propuesta de Anton Tykhyy, aquí hay un pequeño Método de extensión para verificar si algún tipo implementa una interfaz genérica con un tipo de parámetros generics dados:

 public static class ExtensionMethods { ///  /// Checks if a type has a generic interface. /// For example /// mytype.HasGenericInterface(typeof(IList<>), typeof(int)) /// will return TRUE if mytype implements IList ///  public static bool HasGenericInterface(this Type type, Type interf, Type typeparameter) { foreach (Type i in type.GetInterfaces()) if (i.IsGenericType && i.GetGenericTypeDefinition() == interf) if (i.GetGenericArguments()[0] == typeparameter) return true; return false; } } 
 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

Si entiendo tu pregunta correctamente, esto es lo que estás tratando de hacer. Si no, por favor explica más.

 public class MyType : ISomeInterface { } MyType o = new MyType(); if(o is ISomeInterface) { } 

editar: si cambias tu pregunta, agrega el hecho de que editaste … porque ahora mi respuesta parece que no pertenece.

En ese caso, aquí hay un LINQ muy grande

  var item = typeof(MyType).GetInterfaces() .Where(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IList<>)) .Select(t => t.GetGenericArguments().First()) .FirstOrDefault(); if( item != null ) //it has a type