2009-07-29 21 views
5

Estoy tratando de derivar el tipo de un objeto en tiempo de ejecución. Específicamente, necesito saber dos cosas si implementa ICollection o IDto. Actualmente mi única solución que he podido encontrar es la siguiente:¿Cómo puedo comparar tipos cuando uso genéricos?

private static bool IsACollection(PropertyDescriptor descriptor) 
    { 
     bool isCollection = false; 

     foreach (Type type in descriptor.PropertyType.GetInterfaces()) 
     { 
      if (type.IsGenericType) 
      { 
       if (type.GetGenericTypeDefinition() == typeof(ICollection<>)) 
       { 
        isCollection = true; 
        break; 
       } 
      } 
      else 
      { 
       if (type == typeof(ICollection)) 
       { 
        isCollection = true; 
        break; 
       } 
      } 
     } 


     return isCollection; 
    } 

    private static bool IsADto(PropertyDescriptor descriptor) 
    { 
     bool isDto = false; 

     foreach (Type type in descriptor.PropertyType.GetInterfaces()) 
     { 
      if (type == typeof(IDto)) 
      { 
       isDto = true; 
       break; 
      } 
     }   
     return isDto; 
    } 

Sin embargo, estoy convencido de que tiene que haber una manera mejor que esto. He tratado de comparar de una manera normal, tales como:

if(descriptor.PropertyType == typeof(ICollection<>)) 

Sin embargo, esto no funciona cuando se utiliza la reflexión aún cuando no se utiliza la reflexión que trabaja muy bien.

No quiero iterar a través de las interfaces para cada campo de mi entidad. ¿Podría alguien arrojar algo de luz sobre otro método para hacer esto? Sí, estoy optimizando prematuramente, pero también se ve feo, por favor, por favor, cómeme el humor.

Advertencias:

  1. lo que podría o no podría ser genéricos, tales como IList <> ArrayList o simplemente por lo tanto por qué estoy en busca de ICollection o ICollection <>. Así que supongo que debería usar IsGenericType en una declaración if para saber si se prueba usando ICollection <> o no.

¡Gracias de antemano!

Respuesta

11

Este:

type == typeof(ICollection) 

comprobará si el tipo de propiedad es exactamente ICollection. Es decir, se volverá realidad para:

public ICollection<int> x { get; set; } 

pero no para:

public List<int> x { get; set; } 

Si desea comprobar si el tipo de propiedad es, o se deriva de, ICollection, el más simple forma es utilizar Type.IsAssignableFrom:

typeof(ICollection).IsAssignableFrom(type) 

y lo mismo pasa por genéricos:

typeof(ICollection<>).IsAssignableFrom(type.GetGenericTypeDefinition()) 
+0

En realidad él está pasando por toda la jerarquía. Además, ICollection <> no implementa ICollection directamente. – Guvante

+0

Esto lo hizo, tuve el orden de estos comandos invertidos! Estaba haciendo typeof (IList <>). IsAssignableFrom (typeof (ICollection <>). ¡Muchas gracias! – joshlrogers

+0

Esto no funcionó para mí. Tuve que publicar [otra pregunta] (http://stackoverflow.com/q/18937119/122781). – HappyNomad

2

¿Ayuda type.IsAssignable en este caso?

EDIT: Lo sentimos, que debería haber sido Type.IsAssignableFrom

+0

Desafortunadamente no. Cuando compruebo property.PropertyType.IsAssignableFrom (ICollection <>) y el tipo es un IList <>, sigue fallando. Gracias de cualquier forma. – joshlrogers