リフレクションとジェネリック型Reflection and Generic Types

リフレクションの観点から言えば、ジェネリック型は、それがジェネリック型定義である場合は型パラメーター セットが、構築された型である場合は型引数セットが関連付けられているという点で通常の型と異なります。From the point of view of reflection, the difference between a generic type and an ordinary type is that a generic type has associated with it a set of type parameters (if it is a generic type definition) or type arguments (if it is a constructed type). ジェネリック メソッドと通常のメソッドの違いも、それと同様です。A generic method differs from an ordinary method in the same way.

リフレクションでジェネリック型とジェネリック メソッドが処理されるしくみを理解するうえで、次の 2 つの点が重要となります。There are two keys to understanding how reflection handles generic types and methods:

  • ジェネリック型の定義とジェネリック メソッドの定義の型パラメーターは、 Type クラスのインスタンスによって表されます。The type parameters of generic type definitions and generic method definitions are represented by instances of the Type class.

    注意

    Type オブジェクトがジェネリック型パラメーターを表す場合、 Type の多数のプロパティとメソッドの動作が異なります。Many properties and methods of Type have different behavior when a Type object represents a generic type parameter. これらの相違点については、該当するプロパティおよびメソッドに関するトピックに記載されています。These differences are documented in the property and method topics. たとえば、 IsAutoClassDeclaringTypeを参照してください。For example, see IsAutoClass and DeclaringType. さらに、一部のメンバーは Type オブジェクトがジェネリック型パラメーターを表す場合にのみ有効です。In addition, some members are valid only when a Type object represents a generic type parameter. 例については、「 GetGenericTypeDefinition」を参照してください。For example, see GetGenericTypeDefinition.

  • Type のインスタンスがジェネリック型を表す場合、そのインスタンスには、型パラメーター (ジェネリック型の定義の場合) または型引数 (構築された型の場合) を表す型の配列が含まれます。If an instance of Type represents a generic type, then it includes an array of types that represent the type parameters (for generic type definitions) or the type arguments (for constructed types). ジェネリック メソッドを表す MethodInfo クラスのインスタンスの場合も同様です。The same is true of an instance of the MethodInfo class that represents a generic method.

リフレクションが提供する Type および MethodInfo のメソッドを使用すると、型パラメーターの配列にアクセスしたり、Type のインスタンスが型パラメーターと実際の型のどちらを表しているかを確認したりできます。Reflection provides methods of Type and MethodInfo that allow you to access the array of type parameters, and to determine whether an instance of Type represents a type parameter or an actual type.

ここで説明したメソッドを示すコード例については、「方法:リフレクションを使用してジェネリック型をチェックおよびインスタンス化する」に記載された追加情報を参照してください。For example code demonstrating the methods discussed here, see How to: Examine and Instantiate Generic Types with Reflection.

以下の説明は、型パラメーターと型引数の違いや、オープン構築型とクローズ構築型の違いなど、ジェネリックの用語を十分に理解していることを前提としています。The following discussion assumes familiarity with the terminology of generics, such as the difference between type parameters and arguments and open or closed constructed types. 詳細については、「ジェネリック」を参照してください。For more information, see Generics.

ジェネリック型またはジェネリック メソッドであるかどうかの確認Is This a Generic Type or Method?

リフレクションを使用して、 Typeのインスタンスによって表される不明な型を調べる場合は、 IsGenericType プロパティを使用してその不明な型がジェネリックかどうかを確認します。When you use reflection to examine an unknown type, represented by an instance of Type, use the IsGenericType property to determine whether the unknown type is generic. 型がジェネリックの場合、 true を返します。It returns true if the type is generic. 同様に、 MethodInfo クラスのインスタンスによって表される不明なメソッドを調べる場合には、 IsGenericMethod プロパティを使用してそのメソッドがジェネリックかどうかを確認します。Similarly, when you examine an unknown method, represented by an instance of the MethodInfo class, use the IsGenericMethod property to determine whether the method is generic.

ジェネリック型の定義またはジェネリック メソッドの定義であるかどうかの確認Is This a Generic Type or Method Definition?

IsGenericTypeDefinition オブジェクトがジェネリック型の定義を表しているかどうかを確認するには、 Type プロパティを使用します。また、 IsGenericMethodDefinition がジェネリック メソッドの定義を表しているかどうかを確認するには、 MethodInfo メソッドを使用します。Use the IsGenericTypeDefinition property to determine whether a Type object represents a generic type definition, and use the IsGenericMethodDefinition method to determine whether a MethodInfo represents a generic method definition.

ジェネリック型の定義とジェネリック メソッドの定義は、インスタンス化可能な型の作成元となるテンプレートです。Generic type and method definitions are the templates from which instantiable types are created. Dictionary<TKey,TValue>など、.NET Framework クラス ライブラリのジェネリック型は、ジェネリック型の定義ですGeneric types in the .NET Framework class library, such as Dictionary<TKey,TValue>, are generic type definitions.

型またはメソッドがオープンかクローズかIs the Type or Method Open or Closed?

すべての型パラメーター (すべての内包する型のすべての型パラメーターを含む) がインスタンス化可能な型に置き換えられている場合、ジェネリック型またはジェネリック メソッドはクローズであるといいます。A generic type or method is closed if instantiable types have been substituted for all its type parameters, including all the type parameters of all enclosing types. ジェネリック型のインスタンスを作成できるのは、それがクローズである場合だけです。You can only create an instance of a generic type if it is closed. 型がオープンである場合、 Type.ContainsGenericParameters プロパティは true を返します。The Type.ContainsGenericParameters property returns true if a type is open. メソッドの場合、 MethodBase.ContainsGenericParameters メソッドで同じ機能が実行されます。For methods, the MethodBase.ContainsGenericParameters method performs the same function.

クローズ ジェネリック型の生成Generating Closed Generic Types

ジェネリック型の定義を取得したら、 MakeGenericType メソッドを使用してクローズ ジェネリック型を作成します。また、ジェネリック メソッドの定義を取得したら、 MakeGenericMethod メソッドを使用してクローズ ジェネリック メソッドの MethodInfo を作成します。Once you have a generic type or method definition, use the MakeGenericType method to create a closed generic type or the MakeGenericMethod method to create a MethodInfo for a closed generic method.

ジェネリック型の定義またはジェネリック メソッドの定義の取得Getting the Generic Type or Method Definition

ジェネリック型またはジェネリック メソッドの定義ではないオープン ジェネリック型またはオープン ジェネリック メソッドがある場合、そのインスタンスを作成することはできず、欠落している型パラメーターを指定することもできません。If you have an open generic type or method that is not a generic type or method definition, you cannot create instances of it and you cannot supply the type parameters that are missing. ジェネリック型の定義またはジェネリック メソッドの定義が必要です。You must have a generic type or method definition. ジェネリック型の定義を取得するには GetGenericTypeDefinition メソッドを使用し、ジェネリック メソッドの定義を取得するには GetGenericMethodDefinition メソッドを使用します。Use the GetGenericTypeDefinition method to obtain the generic type definition or the GetGenericMethodDefinition method to obtain the generic method definition.

たとえば、 Type (Visual Basic では Dictionary<int, string> ) を表すDictionary(Of Integer, String) オブジェクトがあり、 Dictionary<string, MyClass>型を作成する必要がある場合は、 GetGenericTypeDefinition メソッドを使用して Type を表す Dictionary<TKey, TValue> を取得し、 MakeGenericType メソッドを使用して Type を表す Dictionary<int, MyClass>を作成します。For example, if you have a Type object representing Dictionary<int, string> (Dictionary(Of Integer, String) in Visual Basic) and you want to create the type Dictionary<string, MyClass>, you can use the GetGenericTypeDefinition method to get a Type representing Dictionary<TKey, TValue> and then use the MakeGenericType method to produce a Type representing Dictionary<int, MyClass>.

ジェネリック型ではないオープン ジェネリック型の例は、この後の「型パラメーターまたは型引数」セクションを参照してください。For an example of an open generic type that is not a generic type, see "Type Parameter or Type Argument" later in this topic.

型引数と型パラメーターの確認Examining Type Arguments and Type Parameters

ジェネリック型の型パラメーターまたは型引数を表す Type.GetGenericArguments オブジェクトの配列を取得するには、 Type メソッドを使用します。また、ジェネリック メソッドに対して同じ操作を実行するには、 MethodInfo.GetGenericArguments メソッドを使用します。Use the Type.GetGenericArguments method to obtain an array of Type objects that represent the type parameters or type arguments of a generic type, and use the MethodInfo.GetGenericArguments method to do the same for a generic method.

Type オブジェクトが型パラメーターを表していることがわかったら、リフレクションによって他の多くの詳細を確認できますOnce you know that a Type object represents a type parameter, there are many additional questions reflection can answer. 型パラメーターのソース、その位置、およびその制約を確認できます。You can determine the type parameter's source, its position, and its constraints.

型パラメーターまたは型引数Type Parameter or Type Argument

配列の特定の要素が型パラメーターと型引数のどちらであるかを確認するには、 IsGenericParameter プロパティを使用します。To determine whether a particular element of the array is a type parameter or a type argument, use the IsGenericParameter property. 要素が型パラメーターの場合、 IsGenericParameter プロパティは true です。The IsGenericParameter property is true if the element is a type parameter.

ジェネリック型には、ジェネリック型の定義がないことがあります。その場合のジェネリック型はオープンであり、型引数と型パラメーターが混在しています。A generic type can be open without being a generic type definition, in which case it has a mixture of type arguments and type parameters. たとえば、次のコードでは、クラス DD の 2 つ目の型パラメーターを Bの 1 つ目の型パラメーターに置き換えることによって作成された型から派生します。For example, in the following code, class D derives from a type created by substituting the first type parameter of D for the second type parameter of B.

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> {};  

Type を表す D<V, W> オブジェクトを取得し、 BaseType プロパティを使用してその基本型を取得した場合、結果として得られる type B<int, V> はオープンであり、ジェネリック型の定義ではありません。If you obtain a Type object representing D<V, W> and use the BaseType property to obtain its base type, the resulting type B<int, V> is open, but it is not a generic type definition.

ジェネリック パラメーターのソースSource of a Generic Parameter

ジェネリック型パラメーターのソースとしては、開発者が今調べている型、外側の型、またはジェネリック メソッドが考えられます。A generic type parameter might come from the type you are examining, from an enclosing type, or from a generic method. ジェネリック型パラメーターのソースを特定するには、次の手順を実行します。You can determine the source of the generic type parameter as follows:

  • まず、 DeclaringMethod プロパティを使用して、型パラメーターのソースがジェネリック メソッドかどうかを判定します。First, use the DeclaringMethod property to determine whether the type parameter comes from a generic method. このプロパティの値が null 参照 (Visual Basic ではNothing ) ではない場合、ソースはジェネリック メソッドです。If the property value is not a null reference (Nothing in Visual Basic), then the source is a generic method.

  • ソースがジェネリック メソッドでない場合は、 DeclaringType プロパティを使用して、ジェネリック型パラメーターが属しているジェネリック型を判定します。If the source is not a generic method, use the DeclaringType property to determine the generic type the generic type parameter belongs to.

型パラメーターがジェネリック メソッドに属している場合、 DeclaringType プロパティはそのジェネリック メソッドを宣言した型を返しますが、これは無関係です。If the type parameter belongs to a generic method, the DeclaringType property returns the type that declared the generic method, which is irrelevant.

ジェネリック パラメーターの位置Position of a Generic Parameter

まれなケースですが、宣言するクラスの型パラメーター リスト内の型パラメーターの位置を確認することが必要な場合があります。In rare situations, it is necessary to determine the position of a type parameter in the type parameter list of its declaring class. たとえば、上の例の Type 型を表す B<int, V> オブジェクトについて考えてみます。For example, suppose you have a Type object representing the B<int, V> type from the preceding example. GetGenericArguments メソッドからは、型引数のリストが提供されます。 V を調べるときには、 DeclaringMethod プロパティと DeclaringType プロパティを使用してそれがどこからのものかを確認できますThe GetGenericArguments method gives you a list of type arguments, and when you examine V you can use the DeclaringMethod and DeclaringType properties to discover where it comes from. 次に、 GenericParameterPosition プロパティを使用することにより、型パラメーター リストの中でそれが定義されていた位置を判定できます。You can then use the GenericParameterPosition property to determine its position in the type parameter list where it was defined. この例では、 V は、定義された型パラメーター リスト内の 0 (ゼロ) の位置にあります。In this example, V is at position 0 (zero) in the type parameter list where it was defined.

基本データ型とインターフェイスの制約Base Type and Interface Constraints

GetGenericParameterConstraints メソッドを使用すると、基本データ型の制約と型パラメーターのインターフェイス制約を取得できます。Use the GetGenericParameterConstraints method to obtain the base type constraint and interface constraints of a type parameter. 配列の要素の順序は重要ではありません。The order of the elements of the array is not significant. 要素がインターフェイス型の場合、その要素はインターフェイスの制約を表します。An element represents an interface constraint if it is an interface type.

ジェネリック パラメーターの属性Generic Parameter Attributes

GenericParameterAttributes プロパティを使用すると、型パラメーターの変化 (共変性または反変性) と特殊な制約を示す GenericParameterAttributes 値を取得できます。The GenericParameterAttributes property gets a GenericParameterAttributes value that indicates the variance (covariance or contravariance) and the special constraints of a type parameter.

共変性と反変性Covariance and Contravariance

型パラメーターが共変性と反変性のどちらであるかを判定するには、 GenericParameterAttributes.VarianceMask プロパティから返される GenericParameterAttributes 値に GenericParameterAttributes マスクを適用します。To determine whether a type parameter is covariant or contravariant, apply the GenericParameterAttributes.VarianceMask mask to the GenericParameterAttributes value that is returned by the GenericParameterAttributes property. 結果が GenericParameterAttributes.Noneの場合、型パラメーターはインバリアント (不変) です。If the result is GenericParameterAttributes.None, the type parameter is invariant. 共変性と反変性を参照してください。See Covariance and Contravariance.

特殊な制約Special Constraints

型パラメーターの特殊な制約を判定するには、 GenericParameterAttributes.SpecialConstraintMask プロパティから返される GenericParameterAttributes 値に GenericParameterAttributes マスクを適用します。To determine the special constraints of a type parameter, apply the GenericParameterAttributes.SpecialConstraintMask mask to the GenericParameterAttributes value that is returned by the GenericParameterAttributes property. 結果が GenericParameterAttributes.Noneの場合、特殊な制約はありません。If the result is GenericParameterAttributes.None, there are no special constraints. 型パラメーターには、参照型であること、null 非許容値型であること、およびパラメーターなしのコンストラクターを持っていること、という制約が可能です。A type parameter can be constrained to be a reference type, to be a non-nullable value type, and to have a parameterless constructor.

インバリアントInvariants

ジェネリック型のリフレクションで使用される一般的な用語に対するインバリアント条件を記載した表は、 Type.IsGenericTypeを参照してください。For a table of the invariant conditions for common terms in reflection for generic types, see Type.IsGenericType. ジェネリック メソッドに関連するその他の用語については、 MethodBase.IsGenericMethodを参照してください。For additional terms relating to generic methods, see MethodBase.IsGenericMethod.

TitleTitle 説明Description
方法: リフレクションを使用してジェネリック型をチェックおよびインスタンス化する」を参照してください。How to: Examine and Instantiate Generic Types with Reflection TypeMethodInfo のプロパティとメソッドを使用してジェネリック型について調べる方法を説明します。Shows how to use the properties and methods of Type and MethodInfo to examine generic types.
ジェネリックGenerics ジェネリックの機能と .NET Framework におけるサポートについて説明します。Describes the generics feature and how it is supported in the .NET Framework.
方法: リフレクション出力を使用してジェネリック型を定義するHow to: Define a Generic Type with Reflection Emit リフレクション出力を使用して動的アセンブリにジェネリック型を生成する方法について説明します。Shows how to use reflection emit to generate generic types in dynamic assemblies.
型情報の表示Viewing Type Information Type クラスについて説明します。また、Type をさまざまなリフレクション クラスと共に使用して、コンストラクター、メソッド、フィールド、プロパティ、およびイベントについての情報を取得する方法を示すコード例を提供します。Describes the Type class and provides code examples that illustrate how to use Type with various reflection classes to obtain information about constructors, methods, fields, properties, and events.