2009-10-30 4 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 –

答えて

22

あなたは

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

EDITを使用することができます。IsGenericTypeチェックを追加し、有益なコメントに感謝します、したがって、非ジェネリックタイプにGetGenericTypeDefinition()を呼び出すことはできません

+2

それはですかなり悪い尻、そこに。 –

+2

型がgenericでない場合、 'InvalidOperationException'がスローされます。チェックIMHOのための非常に良い解決策ではありません。 – Lucero

+3

これは、 'theType'がtypeof(IEnumerable <>)とまったく同じで、型がインタフェースを実装していない場合にのみ機能します。うまくいけばそれはあなたが何をしているのかです。 –

2

注意、IsGenericTypeとの最初のチェック。

タイプに汎用IEnumerable<>が実装されているかどうかを確認したい場合、またはインターフェイスタイプがIEnumerable<>かどうかを確認する場合はよく分かりません。特定のタイプIEnumerable<T>インタフェースを実装するかどうかを判断するためのコードのこの部分を使用することができ

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インターフェイスを参照していますか? –

+0

私の質問を明確にします... –

+0

一般的なものは非ジェネリックなものを意味するので、それはインターフェイスをまったく検討する価値があることを確認するための迅速なチェックです。 'IEnumerable'(非ジェネリック)が実装されていない場合、' IEnumerable <> '(ジェネリック)はどちらにもなり得ません。 – Lucero

4

:最初のケースでは、次のコードを(interfaceType有する内側チェックが第二のケースである)を使用します。しかし、それはない仕事の種類はあなたが合格するかどう

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

関連する問題