次の方法で共有


リフレクションとジェネリックの概要

更新 : 2007 年 11 月

リフレクションでジェネリック型とジェネリック メソッドを処理するしくみを理解するうえで、次の 2 つの点が重要となります。

  • ジェネリック型の定義とジェネリック メソッドの定義の型パラメータは、Type クラスのインスタンスによって表されます。

    メモ :

    Type オブジェクトがジェネリック型パラメータを表す場合、Type の多数のプロパティとメソッドにはさまざまな動作があります。これらの相違点については、該当のプロパティおよびメソッドに関するトピックに記載されています。たとえば、IsAutoClass および DeclaringType のトピックを参照してください。また、一部のメンバは、Type オブジェクトがジェネリック型パラメータを表す場合にのみ有効です。たとえば、「GetGenericTypeDefinition」を参照してください。

  • Type のインスタンスがジェネリック型を表す場合、そのインスタンスには、型パラメータ (ジェネリック型の定義の場合) または型引数 (構築された型の場合) を表す型の配列が含まれます。これは、ジェネリック メソッドを表す MethodInfo クラスのインスタンスの場合も同様です。

リフレクションが提供する Type および MethodInfo のメソッドを使用すると、型パラメータの配列にアクセスしたり、Type のインスタンスが型パラメータと実際の型のどちらを表しているかを確認したりできます。

ここで説明するメソッドを示すプログラム例については、「方法 : リフレクションを使用してジェネリック型をチェックおよびインスタンス化する」を参照してください。

以下の説明は、型パラメータと型引数の違いや、オープン構築型とクローズ構築型の違いなど、ジェネリックの用語を十分に理解していることを前提としています。詳細については、「.NET Framework のジェネリックの概要」を参照してください。

ジェネリック型またはジェネリック メソッドかどうかの確認

リフレクションを使用して、Type のインスタンスによって表される不明な型を調べる場合は、IsGenericType プロパティを使用してその不明な型がジェネリックかどうかを確認します。型がジェネリックの場合、このプロパティは true を返します。同様に、MethodInfo クラスのインスタンスによって表される不明なメソッドを調べる場合には、IsGenericMethod プロパティを使用してそのメソッドがジェネリックかどうかを確認します。

ジェネリック型の定義またはジェネリック メソッドの定義かどうかの確認

Type オブジェクトがジェネリック型の定義を表しているかどうかを確認するには、IsGenericTypeDefinition プロパティを使用します。また、MethodInfo がジェネリック メソッドの定義を表しているかどうかを確認するには、IsGenericMethodDefinition メソッドを使用します。

ジェネリック型の定義とジェネリック メソッドの定義は、インスタンス化可能な型の作成元となるテンプレートです。Dictionary<TKey, TValue> など、.NET Framework クラス ライブラリのジェネリック型はジェネリック型の定義です。

型またはメソッドが開いているか閉じているか

すべての型パラメータがインスタンス化可能な型に置き換えられている場合、ジェネリック型またはジェネリック メソッドは閉じています。ジェネリック型が閉じている場合、作成できるのはジェネリック型のインスタンスだけです。型が開いている場合、Type.ContainsGenericParameters プロパティは true を返します。メソッドの場合、MethodInfo.ContainsGenericParameters メソッドは同じ関数を実行します。

クローズ ジェネリック型の生成

ジェネリック型の定義を取得したら、MakeGenericType メソッドを使用してクローズ ジェネリック型を作成します。また、ジェネリック メソッドの定義を取得したら、MakeGenericMethod メソッドを使用して閉じたジェネリック メソッドの MethodInfo を作成します。

ジェネリック型またはジェネリック メソッドの定義の取得

ジェネリック型またはジェネリック メソッドの定義ではないオープン ジェネリック型またはジェネリック メソッドの場合、そのインスタンスを作成することはできません。また、欠落した型パラメータを指定することもできません。ジェネリック型またはジェネリック メソッドの定義が必要です。ジェネリック型の定義を取得するには、GetGenericTypeDefinition メソッドを使用します。また、ジェネリック メソッドの定義を取得するには、GetGenericMethodDefinition メソッドを使用します。

たとえば、Dictionary<int, string> (Visual Basic では Dictionary(Of Integer, String)) を表す Type オブジェクトがあり、Dictionary<string, MyClass> 型を作成する場合、GetGenericTypeDefinition メソッドを使用して Dictionary<TKey, TValue> を表す Type を取得し、MakeGenericType メソッドを使用して Dictionary<int, MyClass> を表す Type を作成します。

ジェネリック型ではないオープン ジェネリック型の例については、このトピックの「型パラメータまたは型引数」を参照してください。

型引数と型パラメータのチェック

ジェネリック型の型パラメータまたは型引数を表す Type オブジェクトの配列を取得するには、Type.GetGenericArguments メソッドを使用します。ジェネリック メソッドの場合は、MethodInfo.GetGenericArguments メソッドを使用します。

Type オブジェクトが型パラメータを表していることがわかったら、リフレクションによって他の詳細も確認できます。型パラメータのソース、位置、および制約を確認できます。

型パラメータまたは型引数

配列の特定の要素が型パラメータと型引数のどちらであるかを確認するには、IsGenericParameter プロパティを使用します。要素が型パラメータの場合、IsGenericParameter プロパティは true です。

ジェネリック型の定義がない場合、ジェネリック型は開いている可能性があります。この場合、そのジェネリック型には型引数と型パラメータが混在しています。たとえば、次のコードでは、D クラスは B の 2 つ目の型パラメータを D の 1 つ目の型パラメータに置き換えることによって作成された型から派生します。

class B<T, U> {}
class D<V, W> : B<int, V> {}
Class B(Of T, U)
End Class
Class D(Of V, W)
    Inherits B(Of Integer, V)
End Class
generic<typename T, typename U> ref class B {};
generic<typename V, typename W> ref class D : B<int, V> {};

D<V, W> を表す Type オブジェクトを取得し、BaseType プロパティを使用してその基本型を取得した場合、結果として得られた type B<int, V> は開いていますが、ジェネリック型の定義ではありません。

ジェネリック パラメータのソース

ジェネリック型パラメータのソースは、開発者が調べた型、外側の型、またはジェネリック メソッドのいずれかです。ジェネリック型パラメータのソースは、次の手順で確認できます。

  • まず、DeclaringMethod プロパティを使用して、型パラメータのソースがジェネリック メソッドかどうかを確認します。プロパティ値が null 参照 (Visual Basic では Nothing) ではない場合、ソースはジェネリック メソッドです。

  • ソースがジェネリック メソッドではない場合は、DeclaringType プロパティを使用して、そのジェネリック型パラメータが属するジェネリック型を確認します。

型パラメータがジェネリック メソッドに属している場合、DeclaringType プロパティはそのジェネリック メソッドを宣言した型を返しますが、これは無関係です。

ジェネリック パラメータの位置

まれなケースですが、宣言するクラスの型パラメータ リスト内の型パラメータの位置を確認することが必要な場合があります。たとえば、前述の例の B<int, V> 型を表す Type オブジェクトがあるとします。GetGenericArguments メソッドは、型引数のリストを提供します。V を調べるときには、DeclaringMethod プロパティと DeclaringType プロパティを使用して、ソースを確認できます。次に、GenericParameterPosition プロパティを使用して、型パラメータが定義された型パラメータ リスト内の位置を確認できます。この例では、V は、定義された型パラメータ リスト内の 0 (ゼロ) の位置にあります。

基本型の制約とインターフェイスの制約

型パラメータの基本型の制約とインターフェイスの制約を取得するには、GetGenericParameterConstraints メソッドを使用します。配列の要素の順序は重要ではありません。要素がインターフェイス型の場合、その要素はインターフェイスの制約を表します。

特殊な制約

GenericParameterAttributes プロパティは、特殊な制約を示す GenericParameterAttributes 値を取得します。型パラメータは、参照型、null 非許容値型、および既定のコンストラクタを持つように制約できます。

一定の条件

ジェネリック型のリフレクションの一般的な用語に関する一定の条件の一覧については、Type.IsGenericType に関するトピックを参照してください。ジェネリック メソッドに関連する他の用語については、MethodInfo.IsGenericMethod に関するトピックを参照してください。

参照

処理手順

方法 : リフレクションを使用してジェネリック型をチェックおよびインスタンス化する

概念

.NET Framework のジェネリックの概要

型情報の表示

参照

Type

MethodInfo

Type.IsGenericType

MethodInfo.IsGenericMethod