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

Val*_*yev 52 .net c# linq collections types

如何确定对象是否为IEnumerable <T>类型?

码:

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());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

NS.1.Program+<GetInts>d__0
Run Code Online (Sandbox Code Playgroud)

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

 System.Collections.Generic.List`1[System.Int32]
Run Code Online (Sandbox Code Playgroud)

这会返回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>)));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 101

如果你的意思是收藏,那么只需as:

var asEnumerable = i as IEnumerable<int>;
if(asEnumerable != null) { ... }
Run Code Online (Sandbox Code Playgroud)

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

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

if(typeof(IEnumerable<int>).IsAssignableFrom(type)) {...}
Run Code Online (Sandbox Code Playgroud)

会做.如果你不知道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;
}
Run Code Online (Sandbox Code Playgroud)

并致电:

Type t = GetEnumerableType(type);
Run Code Online (Sandbox Code Playgroud)

如果这是null,则不是IEnumerable<T>任何T- 否则检查t.

  • 请记住`System.String`实现`IEnumerable <char>`. (20认同)
  • 如果类型是ICollection <T>,它实现IEnumerable <T>,则if语句不会计算为true.有没有办法告诉它是IEnumerable <T>或它的任何子类? (4认同)
  • @Tymek 确实-我做了很多处理原始、内置类型和集合的库工作-并且几乎总是有必要在应用泛化之前提取诸如`string`之类的场景,正是出于这些原因。 (2认同)

Mar*_*dle 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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Ser*_*ern 14

由于IEnumerable <T>继承IEnumerable(非泛型),如果你不需要知道何时类型只是IEnumerable而不是IEnumerable <T>那么你可以使用:

if (typeof(IEnumerable).IsAssignableFrom(srcType))
Run Code Online (Sandbox Code Playgroud)


Pio*_*yna 7

如何确定对象是否为IEnumerable <T>类型?

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

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