MethodBuilder.DefineGenericParameters(String[]) MethodBuilder.DefineGenericParameters(String[]) MethodBuilder.DefineGenericParameters(String[]) MethodBuilder.DefineGenericParameters(String[]) Method

定義

設定目前方法之泛型型別參數的數目、指定其名稱,並傳回可用於定義其條件約束之 GenericTypeParameterBuilder 物件的陣列。Sets the number of generic type parameters for the current method, specifies their names, and returns an array of GenericTypeParameterBuilder objects that can be used to define their constraints.

public:
 cli::array <System::Reflection::Emit::GenericTypeParameterBuilder ^> ^ DefineGenericParameters(cli::array <System::String ^> ^ names);
public System.Reflection.Emit.GenericTypeParameterBuilder[] DefineGenericParameters (string[] names);
member this.DefineGenericParameters : string[] -> System.Reflection.Emit.GenericTypeParameterBuilder[]
Public Function DefineGenericParameters (names As String()) As GenericTypeParameterBuilder()

參數

names
String[]

字串的陣列,表示泛型型別參數的名稱。An array of strings that represent the names of the generic type parameters.

傳回

GenericTypeParameterBuilder 物件的陣列,表示泛型方法的型別參數。An array of GenericTypeParameterBuilder objects representing the type parameters of the generic method.

例外狀況

已為這個方法定義泛型型別參數。Generic type parameters have already been defined for this method.

-或--or- 這個方法已經完成。The method has been completed already.

-或--or- 已針對目前的方法呼叫 SetImplementationFlags(MethodImplAttributes) 方法。The SetImplementationFlags(MethodImplAttributes) method has been called for the current method.

namesnullnames is null.

-或--or- names 的項目是 nullAn element of names is null.

names 是空陣列。names is an empty array.

範例

下列程式碼範例會建立動態型別DemoType,其中包含動態的泛型方法DemoMethodThe following code example creates a dynamic type, DemoType, which contains the dynamic generic method DemoMethod. 這個方法有兩個泛型型別參數,其中一個是當做參數使用,另一個則做為傳回型別。This method has two generic type parameters, one of which is used as a parameter, and the other as the return type.

執行程式碼時,動態組件會儲存為 DemoGenericMethod1.dll,以及可以使用檢查Ildasm.exe (IL 反組譯工具)When the code is executed, the dynamic assembly is saved as DemoGenericMethod1.dll, and can be examined using the Ildasm.exe (IL Disassembler).

注意

這個程式碼範例會產生只傳回 null 參考的簡單方法主體。This code example generates a simple method body that merely returns a null reference. 如需具有更完整開發之方法主體的程式碼範例,以建立和使用泛型類型,請參閱如何:使用反映發出定義泛型方法For a code example with a more fully developed method body that creates and uses generic types, see How to: Define a Generic Method with Reflection Emit.

using namespace System;
using namespace System::Reflection;
using namespace System::Reflection::Emit;

public ref class GenericReflectionSample
{
};

int main()
{
    // Creating a dynamic assembly requires an AssemblyName
    // object, and the current application domain.
    //
    AssemblyName^ asmName =
        gcnew AssemblyName("EmittedAssembly");
    AppDomain^ domain = AppDomain::CurrentDomain;
    AssemblyBuilder^ sampleAssemblyBuilder =
        domain->DefineDynamicAssembly(asmName,
        AssemblyBuilderAccess::RunAndSave);

    // Define the module that contains the code. For an
    // assembly with one module, the module name is the
    // assembly name plus a file extension.
    ModuleBuilder^ sampleModuleBuilder =
        sampleAssemblyBuilder->DefineDynamicModule(asmName->Name,
        asmName->Name + ".dll");

    TypeBuilder^ sampleTypeBuilder =
        sampleModuleBuilder->DefineType("SampleType",
        TypeAttributes::Public | TypeAttributes::Abstract);

    // Define a Shared, Public method with standard calling
    // conventions. Do not specify the parameter types or the
    // return type, because type parameters will be used for
    // those types, and the type parameters have not been
    // defined yet.
    MethodBuilder^ sampleMethodBuilder =
        sampleTypeBuilder->DefineMethod("SampleMethod",
        MethodAttributes::Public | MethodAttributes::Static);

    // Defining generic parameters for the method makes it a
    // generic method. By convention, type parameters are
    // single alphabetic characters. T and U are used here.
    //
    array<String^>^ genericTypeNames = {"T", "U"};
    array<GenericTypeParameterBuilder^>^ genericTypes =
        sampleMethodBuilder->DefineGenericParameters(
        genericTypeNames);

    // Use the IsGenericMethod property to find out if a
    // dynamic method is generic, and IsGenericMethodDefinition
    // to find out if it defines a generic method.
    Console::WriteLine("Is SampleMethod generic? {0}",
        sampleMethodBuilder->IsGenericMethod);
    Console::WriteLine(
        "Is SampleMethod a generic method definition? {0}",
        sampleMethodBuilder->IsGenericMethodDefinition);

    // Set parameter types for the method. The method takes
    // one parameter, and its type is specified by the first
    // type parameter, T.
    array<Type^>^ parameterTypes = {genericTypes[0]};
    sampleMethodBuilder->SetParameters(parameterTypes);

    // Set the return type for the method. The return type is
    // specified by the second type parameter, U.
    sampleMethodBuilder->SetReturnType(genericTypes[1]);

    // Generate a code body for the method. The method doesn't
    // do anything except return null.
    //
    ILGenerator^ ilgen = sampleMethodBuilder->GetILGenerator();
    ilgen->Emit(OpCodes::Ldnull);
    ilgen->Emit(OpCodes::Ret);

    // Complete the type.
    Type^ sampleType = sampleTypeBuilder->CreateType();

    // To bind types to a dynamic generic method, you must
    // first call the GetMethod method on the completed type.
    // You can then define an array of types, and bind them
    // to the method.
    MethodInfo^ sampleMethodInfo = sampleType->GetMethod("SampleMethod");
    array<Type^>^ boundParameters =
        {String::typeid, GenericReflectionSample::typeid};
    MethodInfo^ boundMethodInfo =
        sampleMethodInfo->MakeGenericMethod(boundParameters);
    // Display a string representing the bound method.
    Console::WriteLine(boundMethodInfo);

    // Save the assembly, so it can be examined with Ildasm.exe.
    sampleAssemblyBuilder->Save(asmName->Name + ".dll");
}

/* This code example produces the following output:
Is SampleMethod generic? True
Is SampleMethod a generic method definition? True
GenericReflectionSample SampleMethod[String,GenericReflectionSample](System.String)
*/
using System;
using System.Reflection;
using System.Reflection.Emit;

class DemoMethodBuilder
{
   
    public static void Main()
    {
        // Creating a dynamic assembly requires an AssemblyName
        // object, and the current application domain.
        //
        AssemblyName asmName = 
            new AssemblyName("DemoMethodBuilder1");
        AppDomain domain = AppDomain.CurrentDomain;
        AssemblyBuilder demoAssembly = 
            domain.DefineDynamicAssembly(
                asmName, 
                AssemblyBuilderAccess.RunAndSave
            );

        // Define the module that contains the code. For an 
        // assembly with one module, the module name is the 
        // assembly name plus a file extension.
        ModuleBuilder demoModule = 
            demoAssembly.DefineDynamicModule(
                asmName.Name, 
                asmName.Name + ".dll"
            );
      
        TypeBuilder demoType = demoModule.DefineType(
            "DemoType", 
            TypeAttributes.Public | TypeAttributes.Abstract
        );

        // Define a Shared, Public method with standard calling
        // conventions. Do not specify the parameter types or the
        // return type, because type parameters will be used for 
        // those types, and the type parameters have not been
        // defined yet.
        MethodBuilder demoMethod = demoType.DefineMethod(
            "DemoMethod", 
            MethodAttributes.Public | MethodAttributes.Static
        );

        // Defining generic parameters for the method makes it a
        // generic method. By convention, type parameters are 
        // single alphabetic characters. T and U are used here.
        //
        string[] typeParamNames = {"T", "U"};
        GenericTypeParameterBuilder[] typeParameters = 
            demoMethod.DefineGenericParameters(typeParamNames);

        // The second type parameter is constrained to be a 
        // reference type.
        typeParameters[1].SetGenericParameterAttributes( 
            GenericParameterAttributes.ReferenceTypeConstraint);

        // Use the IsGenericMethod property to find out if a
        // dynamic method is generic, and IsGenericMethodDefinition
        // to find out if it defines a generic method.
        Console.WriteLine("Is DemoMethod generic? {0}", 
            demoMethod.IsGenericMethod);
        Console.WriteLine("Is DemoMethod a generic method definition? {0}", 
            demoMethod.IsGenericMethodDefinition);

        // Set parameter types for the method. The method takes
        // one parameter, and its type is specified by the first
        // type parameter, T.
        Type[] parms = {typeParameters[0]};
        demoMethod.SetParameters(parms);

        // Set the return type for the method. The return type is
        // specified by the second type parameter, U.
        demoMethod.SetReturnType(typeParameters[1]);

        // Generate a code body for the method. The method doesn't
        // do anything except return null.
        //
        ILGenerator ilgen = demoMethod.GetILGenerator();
        ilgen.Emit(OpCodes.Ldnull);
        ilgen.Emit(OpCodes.Ret);

        // Complete the type.
        Type dt = demoType.CreateType();

        // To bind types to a dynamic generic method, you must 
        // first call the GetMethod method on the completed type.
        // You can then define an array of types, and bind them
        // to the method.
        MethodInfo m = dt.GetMethod("DemoMethod");
        Type[] typeArgs = {typeof(string), typeof(DemoMethodBuilder)};
        MethodInfo bound = m.MakeGenericMethod(typeArgs);
        // Display a string representing the bound method.
        Console.WriteLine(bound);

        // Save the assembly, so it can be examined with Ildasm.exe.
        demoAssembly.Save(asmName.Name + ".dll");
    }
}

/* This code example produces the following output:
Is DemoMethod generic? True
Is DemoMethod a generic method definition? True
DemoMethodBuilder DemoMethod[String,DemoMethodBuilder](System.String)
*/
Imports System.Reflection
Imports System.Reflection.Emit

Class DemoMethodBuilder
   
    Public Shared Sub Main()
        ' Creating a dynamic assembly requires an AssemblyName
        ' object, and the current application domain.
        '
        Dim asmName As New AssemblyName("DemoMethodBuilder1")
        Dim domain As AppDomain = AppDomain.CurrentDomain
        Dim demoAssembly As AssemblyBuilder = _
            domain.DefineDynamicAssembly(asmName, _
                AssemblyBuilderAccess.RunAndSave)

        ' Define the module that contains the code. For an 
        ' assembly with one module, the module name is the 
        ' assembly name plus a file extension.
        Dim demoModule As ModuleBuilder = _
            demoAssembly.DefineDynamicModule( _
                asmName.Name, _
                asmName.Name & ".dll")
      
        Dim demoType As TypeBuilder = demoModule.DefineType( _
            "DemoType", _
            TypeAttributes.Public Or TypeAttributes.Abstract)

        ' Define a Shared, Public method with standard calling
        ' conventions. Do not specify the parameter types or the
        ' return type, because type parameters will be used for 
        ' those types, and the type parameters have not been
        ' defined yet.
        Dim demoMethod As MethodBuilder = _
            demoType.DefineMethod("DemoMethod", _
                MethodAttributes.Public Or MethodAttributes.Static)

        ' Defining generic parameters for the method makes it a
        ' generic method. By convention, type parameters are 
        ' single alphabetic characters. T and U are used here.
        '
        Dim typeParamNames() As String = {"T", "U"}
        Dim typeParameters() As GenericTypeParameterBuilder = _
            demoMethod.DefineGenericParameters(typeParamNames)

        ' The second type parameter is constrained to be a 
        ' reference type.
        typeParameters(1).SetGenericParameterAttributes( _
            GenericParameterAttributes.ReferenceTypeConstraint)

        ' Use the IsGenericMethod property to find out if a
        ' dynamic method is generic, and IsGenericMethodDefinition
        ' to find out if it defines a generic method.
        Console.WriteLine("Is DemoMethod generic? {0}", _
            demoMethod.IsGenericMethod)
        Console.WriteLine("Is DemoMethod a generic method definition? {0}", _
            demoMethod.IsGenericMethodDefinition)

        ' Set parameter types for the method. The method takes
        ' one parameter, and its type is specified by the first
        ' type parameter, T.
        Dim params() As Type = {typeParameters(0)}
        demoMethod.SetParameters(params)

        ' Set the return type for the method. The return type is
        ' specified by the second type parameter, U.
        demoMethod.SetReturnType(typeParameters(1))

        ' Generate a code body for the method. The method doesn't
        ' do anything except return Nothing.
        '
        Dim ilgen As ILGenerator = demoMethod.GetILGenerator()
        ilgen.Emit(OpCodes.Ldnull)
        ilgen.Emit(OpCodes.Ret)

        ' Complete the type.
        Dim dt As Type = demoType.CreateType()

        ' To bind types to a dynamic generic method, you must 
        ' first call the GetMethod method on the completed type.
        ' You can then define an array of types, and bind them
        ' to the method.
        Dim m As MethodInfo = dt.GetMethod("DemoMethod")
        Dim typeArgs() As Type = _
            {GetType(String), GetType(DemoMethodBuilder)}
        Dim bound As MethodInfo = m.MakeGenericMethod(typeArgs)
        ' Display a string representing the bound method.
        Console.WriteLine(bound)

        ' Save the assembly, so it can be examined with Ildasm.exe.
        demoAssembly.Save(asmName.Name & ".dll")
    End Sub  
End Class 

' This code example produces the following output:
'Is DemoMethod generic? True
'Is DemoMethod a generic method definition? True
'DemoMethodBuilder DemoMethod[String,DemoMethodBuilder](System.String)

備註

DefineGenericParameters呼叫方法會使目前的方法成為泛型。Calling the DefineGenericParameters method makes the current method generic. 沒有任何方法可以復原這種變更。There is no way to undo this change. 第二次呼叫這個方法會導致InvalidOperationExceptionCalling this method a second time causes an InvalidOperationException.

您之後可以使用GetGenericArguments方法來抓取泛型方法的型別參數。The type parameters of the generic method can be retrieved later by using the GetGenericArguments method.

依照慣例,型別參數名稱是單一大寫字母。By convention, a type parameter name is a single uppercase letter.

如需詳細資訊,請參閱 MethodBase.IsGenericMethodMethodInfo.GetGenericMethodDefinitionFor more information, see MethodBase.IsGenericMethod and MethodInfo.GetGenericMethodDefinition. 如需泛型型別的詳細資訊Type.IsGenericType,請參閱。For information on generic types, see Type.IsGenericType.

適用於

另請參閱