2011-09-02 9 views
8

私はクラス内のプロパティを表すPropertyInfoの配列を持っています。これらの特性のいくつかは、タイプICollection<T>であるが、Tは、特性を横切って変化する - 私はいくつかICollection<string>有し、いくつかのICollection<int>など私は知っているすべてがコレクションのタイプであるときに、TのタイプをC#Genericコレクションで見つけることができますか?

Iを容易にGetGenericTypeDefinition()メソッドを使用してタイプICollection<>である特性を識別することができます型を取得することは不可能ですが、上の例のint型や文字型型のTを取得することは不可能です。

これを行う方法はありますか?あなたはそれがICollection<X>だろう知っているが、Xがわからない場合は

IDocument item 
PropertyInfo[] documentProperties = item.GetType().GetProperties();  
PropertyInfo property = documentProperties.First(); 
Type typeOfProperty = property.PropertyType; 

if (typeOfProperty.IsGenericType) 
{ 
    Type typeOfProperty = property.PropertyType.GetGenericTypeDefinition(); 

    if (typeOfProperty == typeof(ICollection<>) 
    { 
     // find out the type of T of the ICollection<T> 
     // and act accordingly 
    } 
} 

答えて

8

が、それはGetGenericArgumentsとかなり簡単です:

if (typeOfProperty.IsGenericype) 
{ 
    Type genericDefinition = typeOfProperty.GetGenericTypeDefinition(); 

    if (genericDefinition == typeof(ICollection<>) 
    { 
     // Note that we're calling GetGenericArguments on typeOfProperty, 
     // not genericDefinition. 
     Type typeArgument = typeOfProperty.GetGenericArguments()[0]; 
     // typeArgument is now the type you want... 
    } 
} 

タイプがを実装し、いくつかのタイプがあるとき、それは難しくなるICollection<T>が、それ自体は一般的なものかもしれない。あなたがより良い位置にいるように聞こえる:)

+0

ふざけんなよ!あなたは20秒ほど私を打ち負かす。私たちは十字架に投稿しました:-) – Steven

+1

@スティーブン:ちょうどJon Skeetedがあります! –

+0

typeOfPropertyではなく、genericDefinitionでGetGenericArgumentsを呼び出していました。私の見落としを訂正して、今はすべて正常です。私が削除したコメントにより、あなたのコメントは意味をなさないものになりました。 – Jason

4

私は、これはあなたが探しているものであると信じて:

typeOfProperty.GetGenericArguments()[0]; 

あなた例えば、一般的なリスト<T>のT部分を返すこと。

1

Jonのソリューションは、文脈に応じて、T.が得られます、あなたは例えばなどint型、文字列を取得するために、代わりにゲッター戻り値の型にアクセスする必要があるかもしれません...

// The following example will output "T" 
typeOfProperty = property.PropertyType.GetGenericTypeDefinition(); 
Type genericDefinition = typeOfProperty.GetGenericTypeDefinition(); 
if (genericDefinition == typeof(ICollection<>)) 
{ 
    Type t1 = typeOfProperty.GetGenericArguments()[0]; 
    Console.WriteLine(t1.ToString()); 
} 

// Instead you might need to do something like the following... 
// This example will output the declared type (e.g., "Int32", "String", etc...) 
typeOfProperty = property.GetGetMethod().ReturnType; 
if (typeOfProperty.IsGenericType) 
{ 
    Type t2 = typeOfProperty.GetGenericArguments()[0]; 
    Console.WriteLine(t2.ToString()); 
} 
関連する問題