Reputation: 645
I've got a Type.
How can I tell if it's an IEnumerable<>
?
These:
typeof(IEnumerable<>).IsAssignableFrom(memberType);
typeof(IEnumerable<object>).IsAssignableFrom(memberType);
return false for IEnumerable<int>
Whereas this:
typeof(IEnumerable).IsAssignableFrom(memberType);
returns true for string.
Upvotes: 3
Views: 951
Reputation: 645
Well... I found a way to do it...
private static bool IsGenericEnumerable(this [NotNull] Type type) =>
typeof(IEnumerable<>).IsAssignableFrom(type)
|| typeof(IEnumerable<object>).IsAssignableFrom(type)
|| (typeof(IEnumerable<char>).IsAssignableFrom(type) && type != typeof(string))
|| typeof(IEnumerable<byte>).IsAssignableFrom(type)
|| typeof(IEnumerable<sbyte>).IsAssignableFrom(type)
|| typeof(IEnumerable<ushort>).IsAssignableFrom(type)
|| typeof(IEnumerable<short>).IsAssignableFrom(type)
|| typeof(IEnumerable<uint>).IsAssignableFrom(type)
|| typeof(IEnumerable<int>).IsAssignableFrom(type)
|| typeof(IEnumerable<ulong>).IsAssignableFrom(type)
|| typeof(IEnumerable<long>).IsAssignableFrom(type)
|| typeof(IEnumerable<float>).IsAssignableFrom(type)
|| typeof(IEnumerable<double>).IsAssignableFrom(type)
|| typeof(IEnumerable<decimal>).IsAssignableFrom(type)
|| typeof(IEnumerable<DateTime>).IsAssignableFrom(type);
...but that's kind of horrible and I hope there's a better way.
Upvotes: 1
Reputation: 1062492
Reflection is fun; side note: keep in mind that you can implement IEnumerable<X>
and IEnumerable<Y>
(etc) on the same type, so for simplicity here I'm just reporting the first found arbitrarily:
static void Main()
{
Console.WriteLine(FindFirstIEnumerable(typeof(int))); // null
Console.WriteLine(FindFirstIEnumerable(typeof(string))); // System.Char
Console.WriteLine(FindFirstIEnumerable(typeof(Guid[]))); // System.Guid
Console.WriteLine(FindFirstIEnumerable(typeof(IEnumerable<float>))); // System.Single
}
static Type FindFirstIEnumerable(Type type)
{
if (type == null || !typeof(IEnumerable).IsAssignableFrom(type))
return null; // anything IEnumerable<T> *must* be IEnumerable
if (type.IsInterface && type.IsGenericType
&& type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
{
return type.GetGenericArguments()[0];
}
foreach(var iType in type.GetInterfaces())
{
if (iType.IsGenericType &&
iType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
{
return iType.GetGenericArguments()[0];
}
}
return null;
}
Upvotes: 4