2009-10-30 56 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

相關問題