2012-02-24 16 views
30

¿Cómo puedo determinar si una propiedad es una especie de matriz?Determinar si una propiedad es un tipo de matriz por reflexión

Ejemplo:

public bool IsPropertyAnArray(PropertyInfo property) 
{ 
    // return true if type is IList<T>, IEnumerable<T>, ObservableCollection<T>, etc... 
} 
+1

¿Quiere decir, si la propiedad es una colección? Las cosas que coinciden con tu comentario no son arreglos. –

+2

¿Probablemente quiso decir 'IEnumerable' en lugar de' IEnumerator'? – Groo

+0

@Ben: Bueno, las matrices coinciden con sus criterios (IList e IEnumerable ), pero no todas las cosas que coinciden con sus criterios son matrices.:) – Sven

Respuesta

54

Parece que hace dos preguntas diferentes: si un tipo es una matriz (p. string[]) o cualquier tipo de colección. Para los primeros, simplemente marque property.PropertyType.IsArray.

Para este último, debe decidir cuál es el criterio mínimo al que desea que se ajuste un tipo. Por ejemplo, puede buscar el IEnumerable no genérico usando typeof(IEnumerable).IsAssignableFrom(property.PropertyType). También puede usar esto para interfaces genéricas si conoce el tipo real de T, p. typeof(IEnumerable<int>).IsAssignableFrom(property.PropertyType).

La comprobación del genérico IEnumerable<T> o cualquier otra interfaz genérica sin conocer el valor de T se puede hacer comprobando si property.PropertyType.GetInterface(typeof(IEnumerable<>).FullName) no es null. Tenga en cuenta que no especifiqué ningún tipo para T en ese código. Puede hacer lo mismo para IList<T> o cualquier otro tipo que le interesa

Por ejemplo, podría utilizar el siguiente si desea comprobar si el genérico IEnumerable<T>:.

public bool IsPropertyACollection(PropertyInfo property) 
{ 
    return property.PropertyType.GetInterface(typeof(IEnumerable<>).FullName) != null; 
} 

matrices también implementar IEnumerable, por lo que también devolverán true desde ese método.

+1

Esta implementación extrañaría "colecciones de la vieja escuela", heredada de .Net 1 y que implementa IEnumerable pero no la versión genérica IEnumerable . Son cada vez menos utilizados, pero algunos API los esperan, y son realmente un problema. – Falanwe

+1

@Falanwe: A continuación, utilice el primer método que mencioné, que verifica el IEnumerable no genérico. Realmente depende de sus requisitos, cuál es el mejor. – Sven

+1

Probé tu método con una propiedad que es una cadena y el método devuelve verdadero ... ¿Sabes por qué? – Melursus

11

Si usted quiere saber si la propiedad es una matriz, en realidad es muy fácil:

property.PropertyType.IsArray; 

edición

Si desea saber si es un tipo que implementa IEnumerable, al igual que todos los "tipos de colección", tampoco es muy complicado:

return property.PropertyType.GetInterface("IEnumerable") != null; 
+0

No estoy seguro si eso es lo que OP realmente quería (pero admito que nombrar es un poco engañoso). El tipo personalizado que implementa 'IList ' devolverá false desde esta propiedad. – Groo

+0

de hecho, interpreté mal la pregunta inicialmente. Edité mi respuesta para incluir cualquier IEnumerable – Falanwe

+2

@Falanwe: 'IsSubclassOf' no funciona para las interfaces, solo las clases base. – Sven

2
public static bool IsGenericEnumerable(Type type) 
    { 
     return type.IsGenericType && 
      type.GetInterfaces().Any(
      ti => (ti == typeof (IEnumerable<>) || ti.Name == "IEnumerable")); 
    } 

    public static bool IsEnumerable(Type type) 
    { 
     return IsGenericEnumerable(type) || type.IsArray; 
    } 
0

Para mí la siguiente no está funcionando,

return property.PropertyType.GetInterface(typeof(ICollection<>).FullName) != null; 

Siguiendo estaba trabajando,

typeof(ICollection<>).IsAssignableFrom(property.PropertyType.GetGenericTypeDefinition()) 

Esta es la forma de acceso directo para comprobar ICollection<IInterface> o ICollection<BaseClassInTree>

var property = request as PropertyInfo; 

property.PropertyType.IsGenericType && (typeof(ICollection<>).IsAssignableFrom(property.PropertyType.GetGenericTypeDefinition())) && typeof().IsAssignableFrom(property.PropertyType.GenericTypeArguments[0]) 
16

Exclu ding String clase, ya que califica como una colección porque implementa IEnumerable<char>.

public bool IsPropertyACollection(this PropertyInfo property) 
{ 
    return (!typeof(String).Equals(property.PropertyType) && 
     typeof(IEnumerable).IsAssignableFrom(property.PropertyType)); 
} 
+0

typeof (Cadena) era el cheque que me faltaba –

Cuestiones relacionadas