2009-03-12 14 views
9

Necesito validar un objeto para ver si es nulo, un tipo de valor o IEnumerable<T> donde T es un tipo de valor. Hasta ahora tengo:¿Cómo puedo averiguar si el tipo de un objeto es una subclase de IEnumerable <T> para cualquier tipo de valor T?

if ((obj == null) || 
    (obj .GetType().IsValueType)) 
{ 
    valid = true; 
} 
else if (obj.GetType().IsSubclassOf(typeof(IEnumerable<>))) 
{ 
    // TODO: check whether the generic parameter is a value type. 
} 

por lo que he encontrado que el objeto es nulo, un tipo de valor, o por alguna IEnumerable<T>T; ¿Cómo puedo verificar si ese T es un tipo de valor?

Respuesta

12

(editar - añadió bits de tipo de valor)

Es necesario comprobar todas las interfaces que implementa (tenga en cuenta que podría, en teoría, aplicar IEnumerable<T> para múltiples T):

foreach (Type interfaceType in obj.GetType().GetInterfaces()) 
{ 
    if (interfaceType.IsGenericType 
     && interfaceType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) 
    { 
     Type itemType = interfaceType.GetGenericArguments()[0]; 
     if(!itemType.IsValueType) continue; 
     Console.WriteLine("IEnumerable-of-" + itemType.FullName); 
    } 
} 
+1

Es GetInterfaces suficientemente recursivo que significa que no es necesario que preocuparse de ir hasta el padre tipos? –

+0

@Jon: Creo que sí, sí. –

+1

No necesita ninguna recursión. Una clase implementa una interfaz o no. Es una lista plana, independientemente de cómo las interfaces se "heredan" entre sí. – Tar

0

¿Se puede hacer algo con GetGenericArguments?

0

Mi contribución genérica que comprueba si un determinado tipo (o de sus clases base) implementa una interfaz de tipo T:

public static bool ImplementsInterface(this Type type, Type interfaceType) 
{ 
    while (type != null && type != typeof(object)) 
    { 
     if (type.GetInterfaces().Any(@interface => 
      @interface.IsGenericType 
      && @interface.GetGenericTypeDefinition() == interfaceType)) 
     { 
      return true; 
     } 

     type = type.BaseType; 
    } 

    return false; 
} 
Cuestiones relacionadas