Type.MakeGenericType(Type[]) メソッド

定義

型の配列の要素を現在のジェネリック型定義の型パラメーターで置き換え、結果の構築型を表す Type オブジェクトを返します。

public:
 abstract Type ^ MakeGenericType(... cli::array <Type ^> ^ typeArguments);
public:
 virtual Type ^ MakeGenericType(... cli::array <Type ^> ^ typeArguments);
public abstract Type MakeGenericType (params Type[] typeArguments);
public virtual Type MakeGenericType (params Type[] typeArguments);
abstract member MakeGenericType : Type[] -> Type
abstract member MakeGenericType : Type[] -> Type
override this.MakeGenericType : Type[] -> Type
Public MustOverride Function MakeGenericType (ParamArray typeArguments As Type()) As Type
Public Overridable Function MakeGenericType (ParamArray typeArguments As Type()) As Type

パラメーター

typeArguments
Type[]

現在のジェネリック型の型パラメーターに置き換えられる型の配列。

戻り値

typeArguments の要素を現在のジェネリック型の型パラメーターで置き換えることによって作られる構築型を表す Type

例外

現在の型はジェネリック型の定義を表していません。 つまり、IsGenericTypeDefinitionfalse を返します。

typeArgumentsnullです。

または

typeArguments のどの要素も null です。

typeArguments 内の要素数は現在のジェネリック型定義の型パラメーター数と同じではありません。

または

typeArguments のいずれかの要素が、現在のジェネリック型の対応する型パラメーターに指定された制約を満たしていません。

または

typeArguments には、ポインター型 (IsPointertrue を返します)、参照渡し型 (IsByReftrue を返します)、または Void である要素が含まれています。

呼び出されたメソッドは基底クラスでサポートされていません。 派生クラスには実装を指定しなければなりません。

次の例では、 メソッドを MakeGenericType 使用して、型のジェネリック型定義から構築された型を Dictionary<TKey,TValue> 作成します。 構築された型は、文字列キーを持つ オブジェクトの TestDictionary<TKey,TValue>表します。

using namespace System;
using namespace System::Reflection;
using namespace System::Collections::Generic;

namespace Example
{
    public ref class Test
    {
    public:
        static void CreateConstructedType(void)
        {      
            Console::WriteLine("\r\n--- Create a constructed type"
                " from the generic Dictionary`2 type.");
            
            // Create a type object representing 
            // the generic Dictionary`2 type.
            Type^ genericType = Type::GetType(
                "System.Collections.Generic.Dictionary`2");
            if (genericType != nullptr)
            {  
                DisplayTypeInfo(genericType);
            }
            else
            {
                Console::WriteLine("The type is not found");
                return;
            }
            
            // Create an array of types to substitute for the type
            // parameters of Dictionary`2. 
            // The key is of type string, and the type to be 
            // contained in the Dictionary`2 is Test.
            array<Type^>^ typeArgs = {String::typeid, Test::typeid};
            Type^ constructedType = 
                genericType->MakeGenericType(typeArgs);
            DisplayTypeInfo(constructedType);
            
            // Compare the type objects obtained above to type objects
            // obtained using typeof() and GetGenericTypeDefinition().
            Console::WriteLine("\r\n--- Compare types obtained by"
                " different methods:");

            Type^ definedType = Dictionary<String^, Test^>::typeid;
            Console::WriteLine("\tAre the constructed types "
                "equal? {0}", definedType == constructedType);
            Console::WriteLine("\tAre the generic types equal? {0}", 
                definedType->GetGenericTypeDefinition() == genericType);
        }

    private:
        static void DisplayTypeInfo(Type^ typeToDisplay)
        {   
            Console::WriteLine("\r\n{0}", typeToDisplay);
            Console::WriteLine("\tIs this a generic type definition? "
                "{0}", typeToDisplay->IsGenericTypeDefinition);
            Console::WriteLine("\tIs it a generic type? "
                "{0}", typeToDisplay->IsGenericType);
            
            array<Type^>^ typeArguments = 
                typeToDisplay->GetGenericArguments();
            Console::WriteLine("\tList type arguments ({0}):", 
                typeArguments->Length);
            
            for each (Type^ typeArgument in typeArguments)
            {   
                Console::WriteLine("\t\t{0}", typeArgument);
            }
        }
    };
}

int main(void)
{
    Example::Test::CreateConstructedType();
}

/* This example produces the following output:

--- Create a constructed type from the generic Dictionary`2 type.

System.Collections.Generic.Dictionary`2[KeyType,ValueType]
          Is this a generic type definition? True
          Is it a generic type? True
          List type arguments (2):
                     K
                     V

System.Collections.Generic.Dictionary`2[System.String, Test]
          Is this a generic type definition? False
          Is it a generic type? True
          List type arguments (2):
                     System.String
                     Test

--- Compare types obtained by different methods:
          Are the constructed types equal? True
          Are the generic types equal? True
 */
using System;
using System.Reflection;
using System.Collections.Generic;

public class Test
{
    public static void Main()
    {
        Console.WriteLine("\r\n--- Create a constructed type from the generic Dictionary type.");

        // Create a type object representing the generic Dictionary 
        // type, by omitting the type arguments (but keeping the 
        // comma that separates them, so the compiler can infer the
        // number of type parameters).      
        Type generic = typeof(Dictionary<,>);
        DisplayTypeInfo(generic);

        // Create an array of types to substitute for the type
        // parameters of Dictionary. The key is of type string, and
        // the type to be contained in the Dictionary is Test.
        Type[] typeArgs = { typeof(string), typeof(Test) };

        // Create a Type object representing the constructed generic
        // type.
        Type constructed = generic.MakeGenericType(typeArgs);
        DisplayTypeInfo(constructed);

        // Compare the type objects obtained above to type objects
        // obtained using typeof() and GetGenericTypeDefinition().
        Console.WriteLine("\r\n--- Compare types obtained by different methods:");

        Type t = typeof(Dictionary<String, Test>);
        Console.WriteLine("\tAre the constructed types equal? {0}", t == constructed);
        Console.WriteLine("\tAre the generic types equal? {0}", 
            t.GetGenericTypeDefinition() == generic);
    }

    private static void DisplayTypeInfo(Type t)
    {
        Console.WriteLine("\r\n{0}", t);

        Console.WriteLine("\tIs this a generic type definition? {0}", 
            t.IsGenericTypeDefinition);

        Console.WriteLine("\tIs it a generic type? {0}", 
            t.IsGenericType);

        Type[] typeArguments = t.GetGenericArguments();
        Console.WriteLine("\tList type arguments ({0}):", typeArguments.Length);
        foreach (Type tParam in typeArguments)
        {
            Console.WriteLine("\t\t{0}", tParam);
        }
    }
}

/* This example produces the following output:

--- Create a constructed type from the generic Dictionary type.

System.Collections.Generic.Dictionary`2[TKey,TValue]
        Is this a generic type definition? True
        Is it a generic type? True
        List type arguments (2):
                TKey
                TValue

System.Collections.Generic.Dictionary`2[System.String, Test]
        Is this a generic type definition? False
        Is it a generic type? True
        List type arguments (2):
                System.String
                Test

--- Compare types obtained by different methods:
        Are the constructed types equal? True
        Are the generic types equal? True
 */
open System
open System.Collections.Generic

type Test() = class end

let displayTypeInfo (t: Type) =
    printfn $"\r\n{t}"

    printfn $"\tIs this a generic type definition? {t.IsGenericTypeDefinition}" 

    printfn $"\tIs it a generic type? {t.IsGenericType}"

    let typeArguments = t.GetGenericArguments()
    printfn $"\tList type arguments ({typeArguments.Length}):"
    for tParam in typeArguments do
        printfn $"\t\t{tParam}"

printfn "\r\n--- Create a constructed type from the generic Dictionary type."

// Create a type object representing the generic Dictionary 
// type, by calling .GetGenericTypeDefinition().
let generic = typeof<Dictionary<_,_>>.GetGenericTypeDefinition()
displayTypeInfo generic

// Create an array of types to substitute for the type
// parameters of Dictionary. The key is of type string, and
// the type to be contained in the Dictionary is Test.
let typeArgs = [| typeof<string>; typeof<Test> |]

// Create a Type object representing the constructed generic type.
let constructed = generic.MakeGenericType typeArgs
displayTypeInfo constructed

(* This example produces the following output:

--- Create a constructed type from the generic Dictionary type.

System.Collections.Generic.Dictionary`2[TKey,TValue]
        Is this a generic type definition? True
        Is it a generic type? True
        List type arguments (2):
                TKey
                TValue

System.Collections.Generic.Dictionary`2[System.String, Test]
        Is this a generic type definition? False
        Is it a generic type? True
        List type arguments (2):
                System.String
                Test
 *)
Imports System.Reflection
Imports System.Collections.Generic

Public Class Test
    Public Shared Sub Main()
        Console.WriteLine(vbCrLf & "--- Create a constructed type from the generic Dictionary type.")

        ' Create a type object representing the generic Dictionary 
        ' type, by omitting the type arguments (but keeping the 
        ' comma that separates them, so the compiler can infer the
        ' number of type parameters).
        Dim generic As Type = GetType(Dictionary(Of ,))
        DisplayTypeInfo(generic)

        ' Create an array of types to substitute for the type
        ' parameters of Dictionary. The key is of type string, and
        ' the type to be contained in the Dictionary is Test.
        Dim typeArgs() As Type = { GetType(String), GetType(Test) }

        ' Create a Type object representing the constructed generic
        ' type.
        Dim constructed As Type = generic.MakeGenericType(typeArgs)
        DisplayTypeInfo(constructed)

        ' Compare the type objects obtained above to type objects
        ' obtained using GetType() and GetGenericTypeDefinition().
        Console.WriteLine(vbCrLf & "--- Compare types obtained by different methods:")

        Dim t As Type = GetType(Dictionary(Of String, Test))
        Console.WriteLine(vbTab & "Are the constructed types equal? " _
            & (t Is constructed))
        Console.WriteLine(vbTab & "Are the generic types equal? " _ 
            & (t.GetGenericTypeDefinition() Is generic))
    End Sub

    Private Shared Sub DisplayTypeInfo(ByVal t As Type)
        Console.WriteLine(vbCrLf & t.ToString())

        Console.WriteLine(vbTab & "Is this a generic type definition? " _ 
            & t.IsGenericTypeDefinition)

        Console.WriteLine(vbTab & "Is it a generic type? " _ 
            & t.IsGenericType)

        Dim typeArguments() As Type = t.GetGenericArguments()
        Console.WriteLine(vbTab & "List type arguments ({0}):", _
            typeArguments.Length)
        For Each tParam As Type In typeArguments       
            Console.WriteLine(vbTab & vbTab & tParam.ToString())
        Next
    End Sub
End Class

' This example produces the following output:
'
'--- Create a constructed type from the generic Dictionary type.
'
'System.Collections.Generic.Dictionary'2[TKey,TValue]
'        Is this a generic type definition? True
'        Is it a generic type? True
'        List type arguments (2):
'                TKey
'                TValue
'
'System.Collections.Generic.Dictionary`2[System.String,Test]
'        Is this a generic type definition? False
'        Is it a generic type? True
'        List type arguments (2):
'                System.String
'                Test
'
'--- Compare types obtained by different methods:
'        Are the constructed types equal? True
'        Are the generic types equal? True

注釈

MakeGenericTypeメソッドを使用すると、ジェネリック型定義の型パラメーターに特定の型を割り当てるコードを記述できるため、特定の構築された型をType表すオブジェクトを作成できます。 この Type オブジェクトを使用して、構築された型のランタイム インスタンスを作成できます。

MakeGenericType 構築された型は開くことができます。つまり、型引数の一部は、ジェネリック メソッドまたは型を囲む型パラメーターにすることができます。 動的アセンブリを出力するときに、このようなオープン構築型を使用できます。 たとえば、 クラス BaseDerived 次のコードを考えてみましょう。

generic<typename T, typename U>
    public ref class Base { };
generic<typename V>
    public ref class Derived : Base<int, V> { };
public class Base<T, U> { }
public class Derived<V> : Base<int, V> { }
type Base<'T, 'U>() = class end
type Derived<'V>() = inherit Base<int, 'V>()
Public Class Base(Of T, U)
End Class
Public Class Derived(Of V)
    Inherits Base(Of Integer, V)
End Class

動的アセンブリでを生成 Derived するには、その基本型を構築する必要があります。 これを行うには、 のジェネリック型引数と型パラメーターを使用して、 クラスBaseを表す オブジェクトで メソッドTypeを呼び出MakeGenericTypeしますVDerivedInt32 型パラメーターとジェネリック型パラメーターはどちらもオブジェクトによって Type 表されるため、両方を含む配列を メソッドに MakeGenericType 渡すことができます。

Note

などの Base<int, V> 構築された型はコードを出力するときに便利ですが、ジェネリック型定義ではないので、この型で メソッドを呼び出 MakeGenericType すことはできません。 インスタンス化できる閉じた構築型を作成するには、まず メソッドを GetGenericTypeDefinition 呼び出してジェネリック型定義を表すオブジェクトを取得 Type してから、目的の型引数を使用して を呼び出 MakeGenericType します。

によって返されるオブジェクトはType、結果として生成される構築された型のメソッド、またはGetType同じ型引数を使用して同じジェネリック型定義から作成された構築された型のメソッドを呼び出GetTypeして取得した オブジェクトと同じですTypeMakeGenericType

Note

ジェネリック型の配列は、それ自体がジェネリック型ではありません。 ( Visual Basic では ) などのC<T>[]Dim ac() As C(Of T)配列型を呼び出MakeGenericTypeすことはできません。 から C<T>[]閉じたジェネリック型を構築するには、 を呼び出 GetElementType してジェネリック型定義 C<T>を取得します。ジェネリック型定義を呼び出 MakeGenericType して構築された型を作成し、最後に構築された型で メソッドを呼び出 MakeArrayType して配列型を作成します。 ポインターの型と ref 型 (ByRef Visual Basic の場合) についても同様です。

ジェネリック リフレクションで使用する用語に関する一定の条件の一覧については、IsGenericType プロパティの解説を参照してください。

入れ子にされた型

ジェネリック型が C#、C++、または Visual Basic を使用して定義されている場合、その入れ子になった型はすべてジェネリックです。 これは、入れ子になった型に独自の型パラメーターがない場合でも当てはまります。3 つの言語はすべて、入れ子になった型の型パラメーター リストに型を囲む型パラメーターが含まれているためです。 次のクラスについて考えてみましょう。

generic<typename T> public ref class Outermost
{
public:
    generic<typename U> ref class Inner
    {
    public:
        generic<typename V> ref class Innermost1 {};
        ref class Innermost2 {};
    };
};
public class Outermost<T>
{
    public class Inner<U>
    {
        public class Innermost1<V> {}
        public class Innermost2 {}
    }
}
Public Class Outermost(Of T)
    Public Class Inner(Of U)
        Public Class Innermost1(Of V)
        End Class
        Public Class Innermost2
        End Class
    End Class
End Class

入れ子になったクラスInnerの型パラメーター リストには、2 つの型パラメーター と Uがあり、T最初のパラメーターは外側のクラスの型パラメーターです。 同様に、入れ子になったクラスInnermost1の型パラメーター リストには、および Vの 3 つの型パラメーターがあり、UTその外側のクラスとの間TUで取得されます。 入れ子になったクラスには、T外側のクラスInnermost2から取得される 2 つの型パラメーター と Uがあります。

外側の型のパラメーター リストに複数の型パラメーターがある場合、すべての型パラメーターが順番に入れ子になった型の型パラメーター リストに含まれます。

入れ子になった型のジェネリック型定義からジェネリック型を構築するには、外側のすべての型の型引数配列を連結し、最も外側のジェネリック型で始まり、入れ子になった型自体の型引数配列 (独自の型パラメーターがある場合) で終わる配列を使用して、 メソッドを呼び出 MakeGenericType します。 の Innermost1インスタンスを作成するには、T、U、V に割り当てる 3 つの型を含む配列で メソッドを呼び出 MakeGenericType します。の Innermost2インスタンスを作成するには、T と U に MakeGenericType 割り当てる 2 つの型を含む配列で メソッドを呼び出します。

言語は、外側の型の型パラメーターをこの方法で伝達するため、外側の型の型パラメーターを使用して入れ子になった型のフィールドを定義できます。 それ以外の場合、型パラメーターは入れ子になった型の本体内のスコープ内にありません。 動的アセンブリでコードを出力するか、 Ilasm.exe (IL アセンブラー) を使用して、外側の型の型パラメーターを伝達せずに、入れ子になった型を定義できます。 MSIL アセンブラーの次のコードを考えてみましょう。

.class public Outer<T> {
    .class nested public Inner<U> {
        .class nested public Innermost {
        }
    }
}

この例では、型パラメーターがスコープ内にないため、型 T または U クラス Innermostの フィールドを定義することはできません。 次のアセンブラー コードでは、C++、Visual Basic、C# で定義されている場合と同じように動作する入れ子になったクラスを定義します。

.class public Outer<T> {
    .class nested public Inner<T, U> {
        .class nested public Innermost<T, U, V> {
        }
    }
}

Ildasm.exe (IL 逆アセンブラー) を使用して、高レベル言語で定義されている入れ子になったクラスを調べ、この名前付けスキームを確認できます。

適用対象

こちらもご覧ください