Determine if collection is of type IEnumerable<T>
How to determine if object is of type IEnumerable <T>?
Code:
namespace NS {
class Program {
static IEnumerable<int> GetInts() {
yield return 1;
}
static void Main() {
var i = GetInts();
var type = i.GetType();
Console.WriteLine(type.ToString());
}
}
}
Output:
NS.1.Program+<GetInts>d__0
If I change GetInts to return IList, everything is OK the output is:
System.Collections.Generic.List`1[System.Int32]
And this returns false:
namespace NS {
class Program {
static IEnumerable<int> GetInts() {
yield return 1;
}
static void Main() {
var i = GetInts();
var type = i.GetType();
Console.WriteLine(type.Equals(typeof(IEnumerable<int>)));
}
}
}
Solution 1:
If you mean the collection, then just as
:
var asEnumerable = i as IEnumerable<int>;
if(asEnumerable != null) { ... }
However, I'm assuming (from the example) that you have a Type
:
The object will never be "of" type IEnumerable<int>
- but it might implement it; I would expect that:
if(typeof(IEnumerable<int>).IsAssignableFrom(type)) {...}
would do. If you don't know the T
(int
in the above), then check all the implemented interfaces:
static Type GetEnumerableType(Type type) {
if (type.IsInterface && type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
return type.GetGenericArguments()[0];
foreach (Type intType in type.GetInterfaces()) {
if (intType.IsGenericType
&& intType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) {
return intType.GetGenericArguments()[0];
}
}
return null;
}
and call:
Type t = GetEnumerableType(type);
if this is null, it isn't IEnumerable<T>
for any T
- otherwise check t
.
Solution 2:
Since IEnumerable<T> inherit IEnumerable (non generic) and if you don't need to know when a type is just IEnumerable and not IEnumerable<T> then you can use:
if (typeof(IEnumerable).IsAssignableFrom(srcType))
Solution 3:
Same technique as Marc's answer, but Linqier:
namespace NS
{
class Program
{
static IEnumerable<int> GetInts()
{
yield return 1;
}
static void Main()
{
var i = GetInts();
var type = i.GetType();
var isEnumerableOfT = type.GetInterfaces()
.Any(ti => ti.IsGenericType
&& ti.GetGenericTypeDefinition() == typeof(IEnumerable<>));
Console.WriteLine(isEnumerableOfT);
}
}
}
Solution 4:
How to determine if object is of type IEnumerable <T>?
Please feel free to use this fine, ultra small, generic extension method to determine if any object implements IEnumerable interface. It extends the Object type, so you can execute it using any instance of any object you're using.
public static class CollectionTestClass
{
public static Boolean IsEnumerable<T>(this Object testedObject)
{
return (testedObject is IEnumerable<T>);
}
}
Solution 5:
i
is of type NS.1.Program+<GetInts>d__0
, which is a subtype of IEnumerable<int>
. Thus, you can use either
if (i is IEnumerable<int>) { ... }
or IsAssignableFrom
(like in Marc's answer).