How to know if a PropertyInfo is a collection

Viewed 38515

Below is some code I use to get the initial state of all public properties in a class for IsDirty checking.

What's the easiest way to see if a property is IEnumerable?

Cheers,
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);
    }

UPDATE

What I wound up doing was adding a few library extensions as follows

    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);
    }
4 Answers

You can also use "pattern matching". This works for both List<T> and IEnumerable<T>.

private void OutputPropertyValues(object obj)
{
    var properties = obj.GetType().GetProperties();

    foreach (var property in properties)
    {
        if (property.GetValue(obj, null) is ICollection items)
        {
            _output.WriteLine($"    {property.Name}:");

            foreach (var item in items)
            {
                _output.WriteLine($"        {item}");
            }
        }
        else
        {
            _output.WriteLine($"    {property.Name}: {property.GetValue(obj, null)}");
        }
    }
}
Related