Type.MakeGenericType メソッドとは? わかりやすく解説

Weblio 辞書 > コンピュータ > .NET Framework クラス ライブラリ リファレンス > Type.MakeGenericType メソッドの意味・解説 

Type.MakeGenericType メソッド

メモ : このメソッドは、.NET Framework version 2.0 で新しく追加されたものです。

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

名前空間: System
アセンブリ: mscorlib (mscorlib.dll 内)
構文構文

Public Overridable Function
 MakeGenericType ( _
    ParamArray typeArguments As Type() _
) As Type
Dim instance As Type
Dim typeArguments As Type()
Dim returnValue As Type

returnValue = instance.MakeGenericType(typeArguments)
public virtual Type MakeGenericType (
    params Type[] typeArguments
)
public:
virtual Type^ MakeGenericType (
    ... array<Type^>^ typeArguments
)
public Type MakeGenericType (
    Type[] typeArguments
)
public function MakeGenericType (
    ... typeArguments : Type[]
) : Type

パラメータ

typeArguments

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

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

例外例外
例外の種類条件

InvalidOperationException

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

ArgumentNullException

typeArguments が null 参照 (Visual Basic では Nothing) です。

または

typeArguments の要素が null 参照 (Visual Basic では Nothing) です。

ArgumentException

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

または

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

解説解説

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

MakeGenericType によって構築した型は開いた型にすることができます。つまり、これらの型の型引数のいくつかは、包含するジェネリック メソッドまたはジェネリック型の型パラメータにすることができます。動的なアセンブリを出力する場合に、このようなオープン構築型を使用する場合があります。たとえば、次のコードの Base クラスや Derived クラスについて考えてみましょう。

Public Class Base(Of T,
 U)
End Class
Public Class Derived(Of
 V)
    Inherits Base(Of Integer,
 V)
End Class
public class Base<T, U> { }
public class Derived<V> : Base<int,
 V> { }

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

メモメモ

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

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

メモメモ

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

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

入れ子にされた型

ジェネリック型が C#、C++、または Visual Basic を使用して定義されている場合、入れ子にされた型はすべてジェネリックです。入れ子にされた型がその型自体の型パラメータを持っていない場合でも同様です。これら 3 種類の言語にはいずれも入れ子にされた型の型パラメータ リストに包含する型の型パラメータが含まれているからです。次のクラスについて考えてみましょう。

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
public class Outermost<T>
{
    public class Inner<U>
    {
        public class Innermost1<V> {}
        public class Innermost2 {}
    }
}
generic<typename T> public ref class
 Outermost
{
public:
    generic<typename U> ref class Inner
    {
    public:
        generic<typename V> ref class Innermost1 {};
        ref class Innermost2 {};
    };
};

入れ子になったクラス Inner の型パラメータ リストには 2 つの型パラメータ (T と U) が含まれています。最初の型パラメータは、外側のクラスの型パラメータです。同様に、入れ子になったクラス Innermost1 の型パラメータ リストには 3 つの型パラメータ (T、U、および V) が含まれています。T と U は、外側のクラスの型パラメータです。入れ子になったクラス Innermost2 には 2 つの型パラメータ (T と U) が含まれています。これらは外側のクラスの型パラメータです。

包含する型のパラメータ リストに複数の型パラメータが含まれている場合、入れ子にされた型の型パラメータ リストにはすべての型パラメータが順番に含まれます。

入れ子にされた型のジェネリック型定義からジェネリック型を構築するには、すべての包含する型の型引数配列を連結して作られた配列を指定して MakeGenericType メソッドを呼び出します。この配列は一番外側がジェネリック型で始まり、入れ子にされた型の型引数配列で終了します (固有の型パラメータを持っている場合)。Innermost1 のインスタンスを作成するには、T、U、および V に割り当てられる 3 つの型を含む配列を指定して MakeGenericType メソッドを呼び出します。Innermost2 のインスタンスを作成するには、T および U に割り当てられる 2 つの型を含む配列を指定して MakeGenericType メソッドを呼び出します。

このようにして各言語で包含する型の型パラメータが反映されるので、包含する型の型パラメータを使用して、入れ子にされた型のフィールドを定義できます。そうでない場合は、型パラメータは入れ子にされた型の本体内のスコープに入りません。動的なアセンブリでコードを出力するか、または MSIL アセンブラ (Ilasm.exe) を使用すると、包含する型の型パラメータを反映せずに、入れ子にされた型を定義することもできます。次の MSIL アセンブラのコードについて考えてみます。

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

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

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

使用例使用例

MakeGenericType メソッドを使用して、Dictionary 型のジェネリック型定義から構築型を作成する例を次に示します。構築型は、文字列キーで Test オブジェクト Dictionary を表します。

Imports System
Imports System.Reflection
Imports System.Collections.Generic
Imports Microsoft.VisualBasic

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
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
 */
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
 */
プラットフォームプラットフォーム
バージョン情報バージョン情報
参照参照



英和和英テキスト翻訳

英語⇒日本語日本語⇒英語

辞書ショートカット

すべての辞書の索引

「Type.MakeGenericType メソッド」の関連用語

Type.MakeGenericType メソッドのお隣キーワード
検索ランキング

   

英語⇒日本語
日本語⇒英語
   



Type.MakeGenericType メソッドのページの著作権

   
日本マイクロソフト株式会社日本マイクロソフト株式会社
© 2026 Microsoft.All rights reserved.

©2026 GRAS Group, Inc.RSS