2010-08-25 16 views
31

A continuación se muestra un código que utilizo para obtener el estado inicial de todas las propiedades públicas en una clase para la comprobación IsDirty.Cómo saber si un PropertyInfo es una colección

¿Cuál es la forma más fácil de ver si una propiedad es IEnumerable?

Saludos,
Berryl

protected virtual Dictionary<string, object> _GetPropertyValues() 
    { 
     return _getPublicPropertiesWithSetters() 
      .ToDictionary(pi => pi.Name, pi => pi.GetValue(this, null)); 
    } 

    private IEnumerable<PropertyInfo> _getPublicPropertiesWithSetters() 
    { 
     return GetType().GetProperties().Where(pi => pi.CanWrite); 
    } 

ACTUALIZACIÓN

Lo que terminé haciendo fue la adición de algunas extensiones de la biblioteca de la siguiente manera

public static bool IsNonStringEnumerable(this PropertyInfo pi) { 
     return pi != null && pi.PropertyType.IsNonStringEnumerable(); 
    } 

    public static bool IsNonStringEnumerable(this object instance) { 
     return instance != null && instance.GetType().IsNonStringEnumerable(); 
    } 

    public static bool IsNonStringEnumerable(this Type type) { 
     if (type == null || type == typeof(string)) 
      return false; 
     return typeof(IEnumerable).IsAssignableFrom(type); 
    } 

Respuesta

37
if (typeof(IEnumerable).IsAssignableFrom(pi.PropertyType)) 
+25

Tenga en cuenta que una cadena es un IEnumerable demasiado –

+2

resuelve el problema http://stackoverflow.com/a/40376537/5996253 –

1

Trate

private bool IsEnumerable(PropertyInfo pi) 
{ 
    return pi.PropertyType.IsSubclassOf(typeof(IEnumerable)); 
} 
+3

poco me di cuenta de que 'x.IsSubClassOf (y)' devolverá false si x == y En esta situación, si la propiedad pasó a ser de tipo 'IEnumerable', la función devolvería false. –

+1

Eso es interesante, honestamente nunca usé esta lógica en este contexto exacto, así que me alegro de que lo haya señalado. Gracias. –

12

Estoy de acuerdo con Fedor Soikin pero el hecho de que es Enumerable no quiere decir que no es más que una colección desde la cadena también es Enumerable y devuelve los caracteres de uno en uno ...

Por lo tanto se sugiere emplear

if (typeof(ICollection<>).IsAssignableFrom(pi.PropertyType)) 
+1

Tiene razón sobre la cadena, por supuesto, pero su solución falla (pruébelo con la Lista ()). Ver mi actualización para el código que terminé usando. ¡Aclamaciones! – Berryl

+1

Esto falla porque ningún tipo construido (como 'List ') se puede asignar a un tipo genérico ('ICollection <>') (de hecho, no se puede declarar una variable de tipo 'ICollection <>'). Así que mejor use 'typeof (ICollection)' (según lo sugerido por el editor), lo que también hará que funcione para colecciones no genéricas. –

+0

Mucho más de hecho – Joanvo

Cuestiones relacionadas