.NET反射:检测IEnumerable <t> </t>

时间:2009-10-30 13:44:40

标签: .net reflection generics

我正在尝试检测Type对象的特定实例是否是通用的“IEnumerable”......

我能想到的最好的是:

// theType might be typeof(IEnumerable<string>) for example... or it might not
bool isGenericEnumerable = theType.GetGenericTypeDefinition() == typeof(IEnumerable<object>).GetGenericTypeDefinition()
if(isGenericEnumerable)
{
    Type enumType = theType.GetGenericArguments()[0];
    etc. ...// enumType is now typeof(string) 

但这似乎有点间接 - 是否有更直接/更优雅的方式来做到这一点?

3 个答案:

答案 0 :(得分:22)

您可以使用

if(theType.IsGenericType && theType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
{
    Type underlyingType = theType.GetGenericArguments()[0];
    //do something here
}

编辑:添加了IsGenericType检查,感谢有用的评论

答案 1 :(得分:4)

您可以使用这段代码来确定特定类型是否实现IEnumerable<T>接口。

Type type = typeof(ICollection<string>);

bool isEnumerable = type.GetInterfaces()       // Get all interfaces.
    .Where(i => i.IsGenericType)               // Filter to only generic.
    .Select(i => i.GetGenericTypeDefinition()) // Get their generic def.
    .Where(i => i == typeof(IEnumerable<>))    // Get those which match.
    .Count() > 0;

它适用于任何界面,但如果您传入的类型为IEnumerable<T> 将会有效。

您应该能够修改它以检查传递给每个接口的类型参数。

答案 2 :(得分:2)

请注意,您无法在非通用类型上调用GetGenericTypeDefinition(),因此请先查看IsGenericType

我不确定您是否要检查类型是否实现了通用IEnumerable<>,或者您是否想查看接口类型是否为IEnumerable<>。对于第一种情况,请使用以下代码(内部检查interfaceType是第二种情况):

if (typeof(IEnumerable).IsAssignableFrom(type)) {
    foreach (Type interfaceType in type.GetInterfaces()) {
        if (interfaceType.IsGenericType && (interfaceType.GetGenericTypeDefinition() == typeof(IEnumerable<>))) {
            Console.WriteLine("{0} implements {1} enumerator", type.FullName, interfaceType.FullName); // is a match
        }
    }
}