mardok
mardok

Reputation: 2415

Check using reflection if property is IEnumerable only of reference types but not string or value types

Hello I need to check using reflection whether property is IEnumerable type but not IEnumerable of string and value types, but only IEnumerable of non-string reference types.

Right now I have that part of code:

private bool IsEnumerable(PropertyInfo propertyInfo)
{
    return propertyInfo.PropertyType.GetInterfaces().Contains(typeof(IEnumerable)) &&
           propertyInfo.PropertyType != typeof(string);
}

If property is IEnumerable<MyCustomType> this is ok, but if it is IEnumerable<string> my method should return false.

Upvotes: 1

Views: 1973

Answers (1)

David L
David L

Reputation: 33815

You can inspect the GenericTypeArguments of the implemented IEnumerable<T> interfaces on the type to ensure that it is both not of type string and not a value type:

public static bool IsEnumerable(PropertyInfo propertyInfo)
{
    var propType = propertyInfo.PropertyType;

    var ienumerableInterfaces = propType.GetInterfaces()
            .Where(x => x.IsGenericType && x.GetGenericTypeDefinition() ==
                        typeof(IEnumerable<>)).ToList();

    if (ienumerableInterfaces.Count == 0) return false;

    return ienumerableInterfaces.All(x => 
                x.GenericTypeArguments[0] != typeof(string) &&
                !x.GenericTypeArguments[0].IsValueType);    
}

This updated version appropriately handles cases where there are multiple IEnumerable<T> definitions, where there is no IEnumerable<T> definition, and where the type of the generic implementing class does not match the type parameter of implemented IEnumerable<T>.

Upvotes: 3

Related Questions