如何检查泛型方法的类型T是否为IEnumerable<>循环呢?

时间:2012-09-29 02:17:49

标签: c# generics

我想做这样的事情

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

我不知道在问号的位置做什么。它有可能吗?

3 个答案:

答案 0 :(得分:7)

您正在寻找的是:

if (T is IEnumerable) { .. }

但如果您希望T可以一直是IEnumerable:

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

或检查IEnumerable中的值的类型:

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

不必担心自己检查,编译器会为你做,这是拥有静态类型系统和编译器的好东西之一:)

答案 1 :(得分:0)

有几种方法:

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
        }
    }
}

答案 2 :(得分:0)

您必须检查该类实现的每个接口的开放泛型类型,如下所示:

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

这将允许您确定类型是否实现IEnumerable<T>而实际上并不知道类型T是什么。请记住,该类型可以多次实现IEnumerable<T>

如果您只想要IEnumerable<T>类型参数的类型序列,则可以将上述查询更改为;

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