MethodBuilder::DefineGenericParameters Method (array<String^>^)
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.
Assembly: mscorlib (in mscorlib.dll)
public: array<GenericTypeParameterBuilder^>^ DefineGenericParameters( ... array<String^>^ names )
Parameters
- names
-
Type:
array<System::String^>^
An array of strings that represent the names of the generic type parameters.
Return Value
Type: array<System.Reflection.Emit::GenericTypeParameterBuilder^>^An array of GenericTypeParameterBuilder objects representing the type parameters of the generic method.
| Exception | Condition |
|---|---|
| InvalidOperationException | Generic type parameters have already been defined for this method. -or- The method has been completed already. -or- The SetImplementationFlags method has been called for the current method. |
| ArgumentNullException | names is null. -or- An element of names is null. |
| ArgumentException | names is an empty array. |
Calling the DefineGenericParameters method makes the current method generic. There is no way to undo this change. Calling this method a second time causes an InvalidOperationException.
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.
For more information, see MethodInfo::IsGenericMethod and MethodInfo::GetGenericMethodDefinition. For information on generic types, see Type::IsGenericType.
The 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.
When the code is executed, the dynamic assembly is saved as DemoGenericMethod1.dll, and can be examined using the Ildasm.exe (IL Disassembler).
Note |
|---|
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) */
Available since 2.0
Silverlight
Available since 2.0
