如何判断一个东西是否为IEnumerable<>?

3

我有一个类型。

我怎样才能判断它是不是IEnumerable<>类型?

这些:

typeof(IEnumerable<>).IsAssignableFrom(memberType);
typeof(IEnumerable<object>).IsAssignableFrom(memberType);

IEnumerable<int>返回false

相比之下:

typeof(IEnumerable).IsAssignableFrom(memberType);

对于字符串,返回 true。


调用 memberType.GetInterfaces()。针对每个接口,查看 Type.GetGenericTypeDefinition() - 15ee8f99-57ff-4f92-890c-b56153
5
但是 string 是可以枚举的——你可以迭代它的字符。 - Luaan
你是否拥有一个未知类型的 System.Typeobject - John Alexiou
@Luaan 是的,我知道它是一个“IEnumerable”。但我想找到那些我明确声明为“IEnumerable<T>”的东西。 - Sarov
@ja72 System.Type 具体来说,我有一个 MemberInfo,我可以在其上调用 .GetUnderlyingType() - Sarov
@Luaan...但是IEnumerable<>是一个接口,所以实际上不可能创建一个 - 只能创建实现它的东西。就像String一样。所以我现在问的问题甚至没有意义。我明白了。 - Sarov
2个回答

4

反射很有趣;顺便说一下:请记住您可以在同一类型上实现IEnumerable<X> IEnumerable<Y>(等等),因此在这里我只是随意地报告第一个找到的。

static void Main()
{
    Console.WriteLine(FindFirstIEnumerable(typeof(int))); // null
    Console.WriteLine(FindFirstIEnumerable(typeof(string))); // System.Char
    Console.WriteLine(FindFirstIEnumerable(typeof(Guid[]))); // System.Guid
    Console.WriteLine(FindFirstIEnumerable(typeof(IEnumerable<float>))); // System.Single
}

static Type FindFirstIEnumerable(Type type)
{
    if (type == null || !typeof(IEnumerable).IsAssignableFrom(type))
        return null; // anything IEnumerable<T> *must* be IEnumerable
    if (type.IsInterface && type.IsGenericType
        && type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
    {
        return type.GetGenericArguments()[0];
    }
    foreach(var iType in type.GetInterfaces())
    {
        if (iType.IsGenericType &&
            iType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
        {
            return iType.GetGenericArguments()[0];
        }
    }
    return null;
}


1

嗯...我找到了一种方法...

private static bool IsGenericEnumerable(this [NotNull] Type type) =>
            typeof(IEnumerable<>).IsAssignableFrom(type)
            || typeof(IEnumerable<object>).IsAssignableFrom(type)
            || (typeof(IEnumerable<char>).IsAssignableFrom(type) && type != typeof(string))
            || typeof(IEnumerable<byte>).IsAssignableFrom(type)
            || typeof(IEnumerable<sbyte>).IsAssignableFrom(type)
            || typeof(IEnumerable<ushort>).IsAssignableFrom(type)
            || typeof(IEnumerable<short>).IsAssignableFrom(type)
            || typeof(IEnumerable<uint>).IsAssignableFrom(type)
            || typeof(IEnumerable<int>).IsAssignableFrom(type)
            || typeof(IEnumerable<ulong>).IsAssignableFrom(type)
            || typeof(IEnumerable<long>).IsAssignableFrom(type)
            || typeof(IEnumerable<float>).IsAssignableFrom(type)
            || typeof(IEnumerable<double>).IsAssignableFrom(type)
            || typeof(IEnumerable<decimal>).IsAssignableFrom(type)
            || typeof(IEnumerable<DateTime>).IsAssignableFrom(type);

......但那种方式相当糟糕,我希望有更好的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接