.NET反思:IEnumerable的检测(.NET Reflection: Detecting I

2019-09-02 15:28发布

我试图检测一个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) 

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

Answer 1:

您可以使用

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

编辑:添加IsGenericType检查,感谢您的宝贵意见



Answer 2:

可以使用此片的代码,以确定是否一个特定的类型实现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>

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



Answer 3:

请注意,你不能叫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
        }
    }
}


文章来源: .NET Reflection: Detecting IEnumerable