TypeBuilder.GetConstructor(Type, ConstructorInfo) メソッド

定義

ジェネリック型定義の指定したコンストラクターに対応する、指定した構築済みジェネリック型のコンストラクターを返します。

public:
 static System::Reflection::ConstructorInfo ^ GetConstructor(Type ^ type, System::Reflection::ConstructorInfo ^ constructor);
public static System.Reflection.ConstructorInfo GetConstructor(Type type, System.Reflection.ConstructorInfo constructor);
static member GetConstructor : Type * System.Reflection.ConstructorInfo -> System.Reflection.ConstructorInfo
Public Shared Function GetConstructor (type As Type, constructor As ConstructorInfo) As ConstructorInfo

パラメーター

type
Type

コンストラクターが返される、構築されたジェネリック型。

constructor
ConstructorInfo

typeのジェネリック型定義のコンストラクター。返すtypeのコンストラクターを指定します。

返品

ConstructorInfoのジェネリック型定義に属するコンストラクターを指定する、typeに対応するconstructorのコンストラクターを表すtype オブジェクト。

例外

type はジェネリック型を表しません。

-又は-

typeTypeBuilder型ではありません。

-又は-

constructorの宣言型はジェネリック型定義ではありません。

-又は-

constructorの宣言型は、typeのジェネリック型定義ではありません。

次のコード例には、Sample という名前の型パラメーターを持つ T という名前のジェネリック クラスのソース コードが含まれています。 クラスには、Field 型の T という名前のフィールドと、独自の型パラメーターを持つ GM という名前のジェネリック メソッドU。 メソッド GMは、Sampleのインスタンスを作成し、Uの型パラメーターに対して独自の型パラメーター Sampleを置き換え、その入力パラメーターをFieldに格納します。 このソース コードはコンパイルされますが、使用されません。 Ildasm.exe (IL 逆アセンブラー) で表示し、クラス Exampleによって出力されたコードと比較できます。

クラス Example のコードは、ジェネリック コードを出力するために GetConstructor メソッドを使用する方法を示しています。 クラス MainExample メソッドは、Sample という名前のクラスを含む動的アセンブリを作成し、DefineGenericParameters メソッドを使用して、T という名前の型パラメーターを追加してジェネリックにします。 パラメーターなしのコンストラクターと、Field 型の T という名前のフィールドがクラス Sampleに追加されます。 GMメソッドが追加され、MethodBuilder.DefineGenericParameters メソッドを使用してジェネリック メソッドに変換されます。 GMの型パラメーターには、Uという名前が付けられています。 型パラメーターが定義されると、GM メソッドを使用してMethodBuilder.SetSignatureのシグネチャが追加されます。 戻り値の型がなく、必須またはカスタム修飾子がないため、このメソッドのすべてのパラメーターはnullを除いてparameterTypesされます。parameterTypesメソッドの唯一のパラメーターの型を、メソッドのジェネリック型パラメーターであるUに設定します。 メソッドの本体は、構築された型 Sample<U> (Visual Basic の Sample(Of U)) のインスタンスを作成し、メソッドのパラメーターを Field に割り当ててから、Field の値を出力します。 GetConstructor メソッドは、インスタンスを作成するConstructorInfo命令でSample<U>構築されたジェネリック型のパラメーターなしのコンストラクターを表すOpCodes.Newobjを作成するために使用されます。

ダミー型は、エントリ ポイント メソッドの Mainを保持するように定義されています。 Mainの本体では、静的GM メソッドは、構築されたジェネリック型 Sample<int> (Visual Basic では Sample(Of Integer)) で呼び出され、StringU に置き換わります。

コード例を実行すると、出力されたアセンブリが TypeBuilderGetFieldExample.exeとして保存されます。 TypeBuilderGetFieldExample.exeを実行し、 Ildasm.exe (IL 逆アセンブラー) を使用して、出力されたコードと、コード例自体にコンパイルされた Sample クラスのコードを比較できます。

using System;
using System.Reflection;
using System.Reflection.Emit;

// Compare the MSIL in this class to the MSIL
// generated by the Reflection.Emit code in class
// Example.
public class Sample<T>
{
  public T Field;
  public static void GM<U>(U val)
  {
    Sample<U> s = new Sample<U>();
    s.Field = val;
    Console.WriteLine(s.Field);
  }
}

public class Example
{
    public static void Main()
    {
        AppDomain myDomain = AppDomain.CurrentDomain;
        AssemblyName myAsmName =
            new AssemblyName("TypeBuilderGetFieldExample");
        AssemblyBuilder myAssembly = myDomain.DefineDynamicAssembly(
            myAsmName, AssemblyBuilderAccess.Save);
        ModuleBuilder myModule = myAssembly.DefineDynamicModule(
            myAsmName.Name,
            myAsmName.Name + ".exe");

        // Define the sample type.
        TypeBuilder myType = myModule.DefineType("Sample",
            TypeAttributes.Class | TypeAttributes.Public);

        // Add a type parameter, making the type generic.
        string[] typeParamNames = {"T"};
        GenericTypeParameterBuilder[] typeParams =
            myType.DefineGenericParameters(typeParamNames);

        // Define a default constructor. Normally it would
        // not be necessary to define the default constructor,
        // but in this case it is needed for the call to
        // TypeBuilder.GetConstructor, which gets the default
        // constructor for the generic type constructed from
        // Sample<T>, in the generic method GM<U>.
        ConstructorBuilder ctor = myType.DefineDefaultConstructor(
            MethodAttributes.PrivateScope | MethodAttributes.Public |
            MethodAttributes.HideBySig | MethodAttributes.SpecialName |
            MethodAttributes.RTSpecialName);

        // Add a field of type T, with the name Field.
        FieldBuilder myField = myType.DefineField("Field",
            typeParams[0],
            FieldAttributes.Public);

        // Add a method and make it generic, with a type
        // parameter named U. Note how similar this is to
        // the way Sample is turned into a generic type. The
        // method has no signature, because the type of its
        // only parameter is U, which is not yet defined.
        MethodBuilder genMethod = myType.DefineMethod("GM",
            MethodAttributes.Public | MethodAttributes.Static);
        string[] methodParamNames = {"U"};
        GenericTypeParameterBuilder[] methodParams =
            genMethod.DefineGenericParameters(methodParamNames);

        // Now add a signature for genMethod, specifying U
        // as the type of the parameter. There is no return value
        // and no custom modifiers.
        genMethod.SetSignature(null, null, null,
            new Type[] { methodParams[0] }, null, null);

        // Emit a method body for the generic method.
        ILGenerator ilg = genMethod.GetILGenerator();
        // Construct the type Sample<U> using MakeGenericType.
        Type SampleOfU = myType.MakeGenericType( methodParams[0] );
        // Create a local variable to store the instance of
        // Sample<U>.
        ilg.DeclareLocal(SampleOfU);
        // Call the default constructor. Note that it is
        // necessary to have the default constructor for the
        // constructed generic type Sample<U>; use the
        // TypeBuilder.GetConstructor method to obtain this
        // constructor.
        ConstructorInfo ctorOfU = TypeBuilder.GetConstructor(
            SampleOfU, ctor);
        ilg.Emit(OpCodes.Newobj, ctorOfU);
        // Store the instance in the local variable; load it
        // again, and load the parameter of genMethod.
        ilg.Emit(OpCodes.Stloc_0);
        ilg.Emit(OpCodes.Ldloc_0);
        ilg.Emit(OpCodes.Ldarg_0);
        // In order to store the value in the field of the
        // instance of Sample<U>, it is necessary to have
        // a FieldInfo representing the field of the
        // constructed type. Use TypeBuilder.GetField to
        // obtain this FieldInfo.
        FieldInfo FieldOfU = TypeBuilder.GetField(
            SampleOfU, myField);
        // Store the value in the field.
        ilg.Emit(OpCodes.Stfld, FieldOfU);
        // Load the instance, load the field value, box it
        // (specifying the type of the type parameter, U), and
        // print it.
        ilg.Emit(OpCodes.Ldloc_0);
        ilg.Emit(OpCodes.Ldfld, FieldOfU);
        ilg.Emit(OpCodes.Box, methodParams[0]);
        MethodInfo writeLineObj =
            typeof(Console).GetMethod("WriteLine",
                new Type[] { typeof(object) });
        ilg.EmitCall(OpCodes.Call, writeLineObj, null);
        ilg.Emit(OpCodes.Ret);

        // Emit an entry point method; this must be in a
        // non-generic type.
        TypeBuilder dummy = myModule.DefineType("Dummy",
            TypeAttributes.Class | TypeAttributes.NotPublic);
        MethodBuilder entryPoint = dummy.DefineMethod("Main",
            MethodAttributes.Public | MethodAttributes.Static,
            null, null);
        ilg = entryPoint.GetILGenerator();
        // In order to call the static generic method GM, it is
        // necessary to create a constructed type from the
        // generic type definition for Sample. This can be any
        // constructed type; in this case Sample<int> is used.
        Type SampleOfInt =
            myType.MakeGenericType( typeof(int) );
        // Next get a MethodInfo representing the static generic
        // method GM on type Sample<int>.
        MethodInfo SampleOfIntGM = TypeBuilder.GetMethod(SampleOfInt,
            genMethod);
        // Next get a MethodInfo for GM<string>, which is the
        // instantiation of GM that Main calls.
        MethodInfo GMOfString =
            SampleOfIntGM.MakeGenericMethod( typeof(string) );
        // Finally, emit the call. Push a string onto
        // the stack, as the argument for the generic method.
        ilg.Emit(OpCodes.Ldstr, "Hello, world!");
        ilg.EmitCall(OpCodes.Call, GMOfString, null);
        ilg.Emit(OpCodes.Ret);

        myType.CreateType();
        dummy.CreateType();
        myAssembly.SetEntryPoint(entryPoint);
        myAssembly.Save(myAsmName.Name + ".exe");

        Console.WriteLine(myAsmName.Name + ".exe has been saved.");
    }
}
Imports System.Reflection
Imports System.Reflection.Emit

' Compare the MSIL in this class to the MSIL
' generated by the Reflection.Emit code in class
' Example.
Public Class Sample(Of T)
    Public Field As T
    Public Shared Sub GM(Of U)(ByVal val As U)
        Dim s As New Sample(Of U)
        s.Field = val
        Console.WriteLine(s.Field)
    
    End Sub
End Class 

Public Class Example
    
    Public Shared Sub Main() 
        Dim myDomain As AppDomain = AppDomain.CurrentDomain
        Dim myAsmName As New AssemblyName("TypeBuilderGetFieldExample")
        Dim myAssembly As AssemblyBuilder = _
            myDomain.DefineDynamicAssembly(myAsmName, _
                AssemblyBuilderAccess.Save)
        Dim myModule As ModuleBuilder = _
            myAssembly.DefineDynamicModule(myAsmName.Name, _
                myAsmName.Name & ".exe")
        
        ' Define the sample type.
        Dim myType As TypeBuilder = myModule.DefineType( _
            "Sample", _
            TypeAttributes.Class Or TypeAttributes.Public)
        
        ' Add a type parameter, making the type generic.
        Dim typeParamNames() As String = { "T" }
        Dim typeParams As GenericTypeParameterBuilder() = _
            myType.DefineGenericParameters(typeParamNames)
        
        ' Define a default constructor. Normally it would 
        ' not be necessary to define the default constructor,
        ' but in this case it is needed for the call to
        ' TypeBuilder.GetConstructor, which gets the default
        ' constructor for the generic type constructed from 
        ' Sample(Of T), in the generic method GM(Of U).
        Dim ctor As ConstructorBuilder = _
            myType.DefineDefaultConstructor( _
                MethodAttributes.PrivateScope Or MethodAttributes.Public _
                Or MethodAttributes.HideBySig Or MethodAttributes.SpecialName _
                Or MethodAttributes.RTSpecialName)
        
        ' Add a field of type T, with the name Field.
        Dim myField As FieldBuilder = myType.DefineField( _
            "Field", typeParams(0), FieldAttributes.Public)
        
        ' Add a method and make it generic, with a type 
        ' parameter named U. Note how similar this is to 
        ' the way Sample is turned into a generic type. The
        ' method has no signature, because the type of its
        ' only parameter is U, which is not yet defined.
        Dim genMethod As MethodBuilder = _
            myType.DefineMethod("GM", _
                MethodAttributes.Public Or MethodAttributes.Static)
        Dim methodParamNames() As String = { "U" }
        Dim methodParams As GenericTypeParameterBuilder() = _
            genMethod.DefineGenericParameters(methodParamNames)

        ' Now add a signature for genMethod, specifying U
        ' as the type of the parameter. There is no return value
        ' and no custom modifiers.
        genMethod.SetSignature(Nothing, Nothing, Nothing, _
            New Type() { methodParams(0) }, Nothing, Nothing)
        
        ' Emit a method body for the generic method.
        Dim ilg As ILGenerator = genMethod.GetILGenerator()
        ' Construct the type Sample(Of U) using MakeGenericType.
        Dim SampleOfU As Type = _
            myType.MakeGenericType(methodParams(0))
        ' Create a local variable to store the instance of
        ' Sample(Of U).
        ilg.DeclareLocal(SampleOfU)
        ' Call the default constructor. Note that it is 
        ' necessary to have the default constructor for the
        ' constructed generic type Sample(Of U); use the 
        ' TypeBuilder.GetConstructor method to obtain this 
        ' constructor.
        Dim ctorOfU As ConstructorInfo = _
            TypeBuilder.GetConstructor(SampleOfU, ctor)
        ilg.Emit(OpCodes.Newobj, ctorOfU)
        ' Store the instance in the local variable; load it
        ' again, and load the parameter of genMethod.
        ilg.Emit(OpCodes.Stloc_0)
        ilg.Emit(OpCodes.Ldloc_0)
        ilg.Emit(OpCodes.Ldarg_0)
        ' In order to store the value in the field of the
        ' instance of Sample(Of U), it is necessary to have 
        ' a FieldInfo representing the field of the 
        ' constructed type. Use TypeBuilder.GetField to 
        ' obtain this FieldInfo.
        Dim FieldOfU As FieldInfo = _
            TypeBuilder.GetField(SampleOfU, myField)
        ' Store the value in the field. 
        ilg.Emit(OpCodes.Stfld, FieldOfU)
        ' Load the instance, load the field value, box it
        ' (specifying the type of the type parameter, U), 
        ' and print it.
        ilg.Emit(OpCodes.Ldloc_0)
        ilg.Emit(OpCodes.Ldfld, FieldOfU)
        ilg.Emit(OpCodes.Box, methodParams(0))
        Dim writeLineObj As MethodInfo = _
            GetType(Console).GetMethod("WriteLine", _
                New Type() {GetType(Object)})
        ilg.EmitCall(OpCodes.Call, writeLineObj, Nothing)
        ilg.Emit(OpCodes.Ret)
        
        ' Emit an entry point method; this must be in a
        ' non-generic type.
        Dim dummy As TypeBuilder = _
            myModule.DefineType("Dummy", _
                TypeAttributes.Class Or TypeAttributes.NotPublic)
        Dim entryPoint As MethodBuilder = _
            dummy.DefineMethod("Main", _
                MethodAttributes.Public Or MethodAttributes.Static, _
                Nothing, Nothing)
        ilg = entryPoint.GetILGenerator()
        ' In order to call the static generic method GM, it is
        ' necessary to create a constructed type from the 
        ' generic type definition for Sample. This can be ANY
        ' constructed type; in this case Sample(Of Integer)
        ' is used.
        Dim SampleOfInt As Type = _
            myType.MakeGenericType(GetType(Integer))
        ' Next get a MethodInfo representing the static generic
        ' method GM on type Sample(Of Integer).
        Dim SampleOfIntGM As MethodInfo = _
            TypeBuilder.GetMethod(SampleOfInt, genMethod)
        ' Next get a MethodInfo for GM(Of String), which is the 
        ' instantiation of generic method GM that is called
        ' by Sub Main.
        Dim GMOfString As MethodInfo = _
            SampleOfIntGM.MakeGenericMethod(GetType(String))
        ' Finally, emit the call. Push a string onto
        ' the stack, as the argument for the generic method.
        ilg.Emit(OpCodes.Ldstr, "Hello, world!")
        ilg.EmitCall(OpCodes.Call, GMOfString, Nothing)
        ilg.Emit(OpCodes.Ret)
        
        myType.CreateType()
        dummy.CreateType()
        myAssembly.SetEntryPoint(entryPoint)
        myAssembly.Save(myAsmName.Name & ".exe")
        
        Console.WriteLine(myAsmName.Name & ".exe has been saved.")
    
    End Sub 
End Class

注釈

GetConstructor メソッドは、ジェネリック型定義がConstructorInfo オブジェクトによって表される、構築されたジェネリック型のコンストラクターを表すTypeBuilder オブジェクトを取得する方法を提供します。

たとえば、C# 構文 (Visual Basic の TypeBuilder) の型 G<T> を表す G(Of T) オブジェクトと、ConstructorBuilder のコンストラクターを表す G<T> オブジェクトがあるとします。 G<T>に、構築された型Uのインスタンスを作成する型パラメーター G<U>を持つジェネリック メソッドがあるとします。 構築された型のインスタンスを作成するコードを出力するには、この構築された型のコンストラクターを表す ConstructorInfo オブジェクト (つまり、 G<U>のインスタンスを作成する) が必要です。 これを行うには、最初にMakeGenericType オブジェクトでTypeBuilder メソッドを呼び出し、GenericTypeParameterBuilderを表すU オブジェクトを型引数として指定します。 次に、GetConstructor メソッドの戻り値をパラメーター MakeGenericTypeとして、typeのコンストラクターをパラメーター ConstructorBuilderとして表すG<U> オブジェクトを使用して、constructor メソッドを呼び出します。 戻り値は、関数呼び出しを出力するために必要な ConstructorInfo オブジェクトです。 コード例では、このシナリオを示します。

適用対象