2009-10-30 39 views
11

我试图检测一个Type对象的特定实例是一个通用的“IEnumerable的” ....NET反思:检测的IEnumerable <T>

我能想出的最好的是:

// 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) 

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

+0

请参阅我的跟进:http://stackoverflow.com/questions/1650310/net-reflection-determining-whether-an-array-of-t-would-be-convertible-to-some-o – 2009-10-30 14:57:35

回答

22

您可以使用

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

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

+2

这就是很不好的屁股,就在那里。 – 2009-10-30 13:59:46

+2

如果该类型不是泛型的,它会抛出一个'InvalidOperationException' - 对于一个检查恕我直言,这不是一个很好的解决方案。 – Lucero 2009-10-30 14:02:52

+3

只有'theType'正好是typeof(IEnumerable <>)才有效,如果类型实现接口则不适用。希望这就是你所追求的。 – 2009-10-30 14:05:01

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 
     } 
    } 
} 
+0

这个代码指的是遗留(非泛型)IEnumerable接口? – 2009-10-30 13:57:21

+0

我会澄清我的问题...... – 2009-10-30 13:58:24

+0

是的,因为通用的一个意味着非通用的问题,这是一个快速检查,以确保它有必要通过接口。如果'IEnumerable'(非泛型)没有实现,'IEnumerable <>'(generic)不能。 – Lucero 2009-10-30 13:59:03

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>

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

+0

而不是Where()。Count()可以使用Any()。 – Fred 2016-10-06 12:52:51

相关问题