确定集合是否为IEnumerable <t> </t>类型

时间:2009-12-04 12:30:23

标签: c# .net linq collections types

如何确定对象的类型是否为IEnumerable&lt; T&gt;?

代码:

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());
        }
    }
}

输出:

NS.1.Program+<GetInts>d__0

如果我更改GetInts以返回IList,一切正常 输出是:

 System.Collections.Generic.List`1[System.Int32]

这会返回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>)));
        }
    }
}

10 个答案:

答案 0 :(得分:99)

如果您指的是集合,那么只需as

var asEnumerable = i as IEnumerable<int>;
if(asEnumerable != null) { ... }

但是,我假设(从示例中)您有Type

对象永远不会是“{”类型IEnumerable<int> - 但它可能实现它;我希望如此:

if(typeof(IEnumerable<int>).IsAssignableFrom(type)) {...}

会这样做。如果你不知道T(上面的int),那么检查所有已实现的接口:

static Type GetEnumerableType(Type type) {
    foreach (Type intType in type.GetInterfaces()) {
        if (intType.IsGenericType
            && intType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) {
            return intType.GetGenericArguments()[0];
        }
    }
    return null;
}

并致电:

Type t = GetEnumerableType(type);

如果为空,则IEnumerable<T>不是T - 否则请检查t

答案 1 :(得分:14)

与Marc的答案相同,但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);
        }
    }
}

答案 2 :(得分:14)

因为IEnumerable&lt; T&gt;继承IEnumerable(非泛型),如果你不需要知道何时类型只是IEnumerable而不是IEnumerable&lt; T&gt;然后你可以使用:

if (typeof(IEnumerable).IsAssignableFrom(srcType))

答案 3 :(得分:7)

  

如何确定对象是否属于类型   IEnumerable&lt; T&gt;?

请随意使用这个精细的,超小的通用扩展方法来确定是否有任何对象实现IEnumerable接口。它扩展了 Object 类型,因此您可以使用您正在使用的任何对象的任何实例来执行它。

public static class CollectionTestClass
{
    public static Boolean IsEnumerable<T>(this Object testedObject)
    {
        return (testedObject is IEnumerable<T>);
    }
}

答案 4 :(得分:3)

i属于NS.1.Program+<GetInts>d__0类型,是IEnumerable<int>子类型。因此,您可以使用

if (i is IEnumerable<int>) { ... }

IsAssignableFrom(就像Marc的回答一样)。

答案 5 :(得分:1)

您可以使用is关键字。

[TestFixture]
class Program
{
    static IEnumerable<int> GetInts()
    {
        yield return 1;
    }

    [Test]
    static void Maasd()
    {
        var i = GetInts();
        Assert.IsTrue(i is IEnumerable<int>);
    }
}

答案 6 :(得分:0)

How to detect if type is another generic type可以帮助您解决这个问题。

答案 7 :(得分:0)

尝试

type.GetInterface(“ IEnumerable”)!= null && type.IsGenericType

答案 8 :(得分:0)

我相信解决此问题的最佳方法应该很简单。您首先编写返回IEnumerable<T>的通用参数(或您情况下的参数)的代码,然后编写另一行以对参数进行比较您希望与IEnumerable<T>对象中包含的类型进行比较的类型(在您的情况下为int)。我有一个示例,其中显示了处理两个任务的两个简单函数。

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

答案 9 :(得分:0)

对于那些只想知道如何从IEnumerable或从IEnumerable返回true或false的人,我使用了Marcs原始答案来创建我现在正在使用的这种通用方法。

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