Determine if collection is of type IEnumerable<T>

Viewed 34336

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

Try

type.GetInterface("IEnumerable") != null && type.IsGenericType

I believe the best way to solve this should be simple.. You first write code that returns the generic arguments (or argument in your case) of the IEnumerable<T> then write another line to make a comparison of the argument type you desire to compare to the type contained in the IEnumerable<T> object (int, in your case). I have an example that displays two simple functions that handles both tasks.

    public static Type GetEnumerableArgumentType(Type type)
    {
        if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
            return type.GetGenericArguments()[0];
        else
            return null;            
    }        

    public static bool EnumerableContainsArgumentType(Type tEnumerable, Type tGenArg)
    {
        return GetEnumerableArgumentType(tEnumerable) == tGenArg;
    }

For anyone searching for this who just wants to know how to return true or false on if an object is or inherits from IEnumerable, I've used Marcs original answer to create this generic method I'm now using.

private static bool ImplementsIEnumerable<T>(T obj)
    {
        var type = obj.GetType();
        if (type.IsInterface && type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
        {
            return true;
        }
        foreach (Type interfaceUsed in type.GetInterfaces())
        {
            if (interfaceUsed.IsGenericType
                && interfaceUsed.GetGenericTypeDefinition() == typeof(IEnumerable<>))
            {
                return true;
            }
        }
        return false;
    }
Related