MethodBuilder.DefineGenericParameters(String[]) 方法
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
设置当前方法的泛型类型参数的数目,指定其名称并返回一个可用于定义其约束的 GenericTypeParameterBuilder 对象的数组。
public:
cli::array <System::Reflection::Emit::GenericTypeParameterBuilder ^> ^ DefineGenericParameters(... cli::array <System::String ^> ^ names);
public System.Reflection.Emit.GenericTypeParameterBuilder[] DefineGenericParameters (params string[] names);
member this.DefineGenericParameters : string[] -> System.Reflection.Emit.GenericTypeParameterBuilder[]
Public Function DefineGenericParameters (ParamArray names As String()) As GenericTypeParameterBuilder()
参数
- names
- String[]
一个字符串数组,表示泛型类型参数的名称。
返回
一个 GenericTypeParameterBuilder 对象数组,表示泛型方法的类型参数。
例外
names
是一个空数组。
示例
下面的代码示例创建一个动态类型 DemoType
,其中包含动态泛型方法 DemoMethod
。 此方法有两个泛型类型参数,其中一个用作参数,另一个用作返回类型。
执行代码时,该动态程序集会另存为 DemoGenericMethod1.dll,使用 Ildasm.exe(IL 反汇编程序) 可以对其进行检查。
备注
此代码示例生成仅返回 null 引用的简单方法主体。 有关创建和使用泛型类型的更完善方法主体的代码示例,请参阅 如何:使用反射发出定义泛型方法。
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调用 方法会使当前方法成为泛型方法。 无法撤消此更改。 再次调用此方法会导致 InvalidOperationException。
稍后 GetGenericArguments 可以使用 方法检索泛型方法的类型参数。
按照约定,类型参数名称是一个大写字母。
有关详细信息,请参阅 MethodBase.IsGenericMethod 和 MethodInfo.GetGenericMethodDefinition。 有关泛型类型的信息,请参阅 Type.IsGenericType。