2009-07-17 17 views
24

Tengo una interfaz genérica, por ejemplo, IGeneric. Para un tipo dado, quiero encontrar los argumentos genéricos que una clase impone a través de IGeneric.Obtener argumentos de tipo de interfaces genéricas que implementa una clase

Es más claro en este ejemplo:

Class MyClass : IGeneric<Employee>, IGeneric<Company>, IDontWantThis<EvilType> { ... } 

Type t = typeof(MyClass); 
Type[] typeArgs = GetTypeArgsOfInterfacesOf(t); 

// At this point, typeArgs must be equal to { typeof(Employee), typeof(Company) } 

¿Cuál es la implementación de GetTypeArgsOfInterfacesOf (tipo T)?

Nota: Se puede suponer que el método GetTypeArgsOfInterfacesOf está escrito específicamente para IGeneric.

Edit: Tenga en cuenta que específicamente estoy preguntando cómo filtrar la interfaz IGeneric de todas las interfaces que MyClass implementa.

relacionadas: Finding out if a type implements a generic interface

Respuesta

35

limitarlo a sólo un sabor específico de la interfaz genérica que necesita para obtener la definición de tipo genérico y comparar con el "abrir" la interfaz (IGeneric<> - note ningún "T" especificada):

List<Type> genTypes = new List<Type>(); 
foreach(Type intType in t.GetInterfaces()) { 
    if(intType.IsGenericType && intType.GetGenericTypeDefinition() 
     == typeof(IGeneric<>)) { 
     genTypes.Add(intType.GetGenericArguments()[0]); 
    } 
} 
// now look at genTypes 

O como LINQ consulta de sintaxis:

Type[] typeArgs = (
    from iType in typeof(MyClass).GetInterfaces() 
    where iType.IsGenericType 
     && iType.GetGenericTypeDefinition() == typeof(IGeneric<>) 
    select iType.GetGenericArguments()[0]).ToArray(); 
13
typeof(MyClass) 
    .GetInterfaces() 
    .Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IGeneric<>)) 
    .SelectMany(i => i.GetGenericArguments()) 
    .ToArray(); 
+0

Ok, pero esto implica EvilType de IDontWantThis . No quiero el EvilType. –

+0

Solucionado, solo necesitaba una condición simple en el lugar(). –

2
Type t = typeof(MyClass); 
      List<Type> Gtypes = new List<Type>(); 
      foreach (Type it in t.GetInterfaces()) 
      { 
       if (it.IsGenericType && it.GetGenericTypeDefinition() == typeof(IGeneric<>)) 
        Gtypes.AddRange(it.GetGenericArguments()); 
      } 


public class MyClass : IGeneric<Employee>, IGeneric<Company>, IDontWantThis<EvilType> { } 

    public interface IGeneric<T>{} 

    public interface IDontWantThis<T>{} 

    public class Employee{ } 

    public class Company{ } 

    public class EvilType{ } 
Cuestiones relacionadas