Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect if T is IEnumerable<T2>, and if so get type of T2?

I'm aware of this question, and it's follow-up, and also this one, but I can't put them together in a way which will help me do what I want to do:

I have a generic type, and I want to check that T is a struct OR if it implements IEnumerable<T2>, then I'd like to check that T2 is a struct.

So far, I've got to here ('scuse the scrappy code, this is experimental):

private class TestClass<T>
{
    public TestClass()
    {
        Type type = typeof(T);
        //(detecting T == IEnumerable<something> ommitted for clarity)
        Type enumerableType = type.GetInterfaces()
                .Where(t => t.IsGenericType)
                .Select(t => t.GetGenericTypeDefinition())
                .Where(t => t == typeof(IEnumerable<>))
                .FirstOrDefault();
        if(enumerableType != null) 
        {
            Type enumeratedType = type.GetGenericArguments().First();
            if(!enumeratedType.IsValueType) //throw etc...
        }
    }
}

The problem I have is that enumerableType is IEnumerable<>, so the enumeratedType comes out as T, not whatever I've passed in (eg. new TestClass<int[]>()).

like image 845
Benjol Avatar asked Jan 07 '11 13:01

Benjol


1 Answers

Your problem is that you've selected away the type that has all the data in favor of it's erased generic type template.

Try:

    Type enumerableType = type.GetInterfaces()
            .Where(t => t.IsGenericType)
            .Where(t => t.GetGenericTypeDefinition() == typeof(IEnumerable<>))
            .Select(t => t.GetGenericArguments()[0])
            .FirstOrDefault();
like image 174
Ben Voigt Avatar answered Sep 27 '22 16:09

Ben Voigt