TypeBuilder.GetConstructor(Type, ConstructorInfo) 方法

定義

傳回指定建構泛型類型的建構函式,其對應於泛型類型定義的指定建構函式。

C#
public static System.Reflection.ConstructorInfo GetConstructor(Type type, System.Reflection.ConstructorInfo constructor);

參數

type
Type

傳回的是建構泛型類型的建構函式。

constructor
ConstructorInfo

指定要傳回哪個 type 建構函式 type 之泛型類型定義的建構函式。

傳回

表示對應 constructor (其指定屬於 type 泛型類型定義的建構函式) 的 type 建構函式的 ConstructorInfo 物件,。

例外狀況

type 不代表泛型類型。

-或-

type 不是 TypeBuilder型別。

-或-

constructor 的宣告類型不是泛型類型定義。

-或-

constructor 的宣告類型不是 type 的泛型類型定義。

範例

下列程式代碼範例包含名為 Sample 之泛型類別的原始程式碼,其類型參數為 T。 類別具有名為 Field的欄位、類型 T,以及名為 GM 的泛型方法,其本身的類型參數為 U。 方法GM會建立的Sample實例,將自己的型別參數取代為的Sample型別參數U,並將其輸入參數儲存在 Field中。 此原始碼已編譯,但未使用;您可以使用 Ildasm.exe (IL 反組譯程式) 來檢視它,並將其與 類別 Example發出的程式代碼進行比較。

類別 Example 中的程式代碼示範如何使用 GetConstructor 方法來發出泛型程序代碼。 類別MainExample的 方法會建立包含名為 Sample 的類別的動態元件,並使用 DefineGenericParameters 方法,藉由新增名為T的型別參數來讓它成為泛型。 無參數建構函式和類型 為 FieldT欄位會新增至 類別 Sample。 方法 GM 會使用 MethodBuilder.DefineGenericParameters 方法加入並轉換成泛型方法。 的型別參數 GM 名為 U。 定義型別參數之後,會使用 方法新增 的GMMethodBuilder.SetSignature簽章。 沒有傳回型別,沒有必要或自定義修飾詞,因此此方法的所有參數除外nullparameterTypes;parameterTypes請將方法的唯一參數的類型設定為 U,方法的泛型型別參數。 方法的主體會在 Visual Basic) 中建立建構型 Sample<U> 別 (Sample(Of U) 的實例、將方法的參數指派給 Field,然後列印 的值 Field。 方法GetConstructor可用來建立 ,ConstructorInfo代表建立實例之指令中OpCodes.Newobj建構泛型型Sample<U>別的無參數建構函式。

已定義虛擬類型,以儲存進入點方法 Main。 在 的主體Main中,靜態GM方法會在 Visual Basic () Sample(Of Integer) 中建構的泛型型Sample<int>別上叫用,且型String別取代為 U

執行程式代碼範例時,它會將發出的元件儲存為 TypeBuilderGetFieldExample.exe。 您可以執行 TypeBuilderGetFieldExample.exe,而且您可以使用 Ildasm.exe (IL 反組譯程式) 來比較發出的程式代碼與編譯成程式代碼範例本身之類別的程式代碼 Sample

C#
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.");
    }
}

備註

方法 GetConstructor 提供方法來取得 ConstructorInfo 對象,這個物件表示建構泛型型別的建構函式,其泛型型別定義是由 TypeBuilder 物件表示。

例如,假設您有 一個 TypeBuilder 物件,代表Visual Basic中 C# 語法 (G(Of T) 的型G<T>別、 generic <T> ref class G C++) ,以及ConstructorBuilder代表 建構函式的G<T>物件。 G<T>假設有一個泛型方法,其型別參數U會建立建構型G<U>別的實例。 若要發出程式代碼來建立建構型別的實例,您需要 ConstructorInfo 代表這個建構型別建構函式的 物件,換句話說,它會建立的 G<U>實例。 若要這樣做,請先在 物件上TypeBuilder呼叫 MakeGenericType 方法,並GenericTypeParameterBuilder指定 表示U為類型自變數的物件。 GetConstructor然後使用 方法的MakeGenericType傳回值呼叫 方法做為 參數type,而 ConstructorBuilder 物件則表示 做為 參數 constructorG<U>建構函式。 傳回值是 ConstructorInfo 您需要發出函式呼叫的物件。 程式代碼範例示範此案例。

適用於

產品 版本
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9, 10
.NET Framework 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0 (package-provided), 2.1