tranmq
tranmq

Reputation: 15658

How to check if a type T of a generic method is IEnumerable<> and loop it?

I'd like to do something like this

void DoSomething<T>(T param)
{
    if param is IEnumerable<?>
    {
        loop param and do stuff
    }
}

I don't know what to do in the place of the question mark. And is it possible at all?

Upvotes: 7

Views: 6026

Answers (3)

casperOne
casperOne

Reputation: 74530

You have to check the open generic type of each interface that the class implements, like so:

bool implements = typeof(T).GetInterfaces().Where(t => t.IsGenericType && 
    t.GetGenericTypeDefinition() == typeof(IEnumerable<>)).Any();

This will allow you to determine whether or not a type implements IEnumerable<T> without actually knowing what the type T is. Remember that the type can implement IEnumerable<T> multiple times.

If you simply want the sequence of types that are type parameters for IEnumerable<T>, you can change the above query to;

IEnumerable<Type> types = typeof(T).GetInterfaces().
    Where(t => t.IsGenericType && 
        t.GetGenericTypeDefinition() == typeof(IEnumerable<>)).
    Select(t => t.GetGenericArguments()[0]);

Upvotes: 0

Francisco Soto
Francisco Soto

Reputation: 10392

What you are looking for is :

if (T is IEnumerable) { .. }

but if you expect T to be IEnumerable all the time you can do:

void DoSomething<T>(T param) where T : IEnumerable
{
    foreach (var t in param) { ... }
}

or checking the type of the values inside the IEnumerable:

public void DoSomething<T,U>(T val) where T : IEnumerable<U>
{
    foreach (U a in val)
    {
    }
}

Without having to worry to check it yourself, the compiler will do it for you, which is one of the nice things of having a static type system and compiler :)

Upvotes: 12

decyclone
decyclone

Reputation: 30830

There are a few ways:

void DoSomething<T>(T param)
{
    if (param is IEnumerable)
    {
        foreach (var item in (IEnumerable)param)
        {
            // Do something
        }
    }
}

void DoSomething<T>(T param)
{
    if (param is IEnumerable<string>)
    {
        foreach (var item in (IEnumerable<string>)param)
        {
            // Do something
        }
    }
}

void DoSomething<T,TItem>(T param)
{
    if (param is IEnumerable<TItem>)
    {
        foreach (var item in (IEnumerable<TItem>)param)
        {
            // Do something
        }
    }
}

Upvotes: 0

Related Questions