Reputation: 2415
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
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