Export (0) Print
Expand All

MethodBuilder.SetSignature Method

Sets the method signature, including the return type, the parameter types, and the required and optional custom modifiers of the return type and parameter types.

Namespace:  System.Reflection.Emit
Assembly:  mscorlib (in mscorlib.dll)

public void SetSignature(
	Type returnType,
	Type[] returnTypeRequiredCustomModifiers,
	Type[] returnTypeOptionalCustomModifiers,
	Type[] parameterTypes,
	Type[][] parameterTypeRequiredCustomModifiers,
	Type[][] parameterTypeOptionalCustomModifiers
)

Parameters

returnType
Type: System.Type
The return type of the method.
returnTypeRequiredCustomModifiers
Type: System.Type[]
An array of types representing the required custom modifiers, such as IsConst, for the return type of the method. If the return type has no required custom modifiers, specify null.
returnTypeOptionalCustomModifiers
Type: System.Type[]
An array of types representing the optional custom modifiers, such as IsConst, for the return type of the method. If the return type has no optional custom modifiers, specify null.
parameterTypes
Type: System.Type[]
The types of the parameters of the method.
parameterTypeRequiredCustomModifiers
Type: System.Type[][]
An array of arrays of types. Each array of types represents the required custom modifiers for the corresponding parameter, such as IsConst. If a particular parameter has no required custom modifiers, specify null instead of an array of types. If none of the parameters have required custom modifiers, specify null instead of an array of arrays.
parameterTypeOptionalCustomModifiers
Type: System.Type[][]
An array of arrays of types. Each array of types represents the optional custom modifiers for the corresponding parameter, such as IsConst. If a particular parameter has no optional custom modifiers, specify null instead of an array of types. If none of the parameters have optional custom modifiers, specify null instead of an array of arrays.

ExceptionCondition
InvalidOperationException

The current method is generic, but is not a generic method definition. That is, the IsGenericMethod property is true, but the IsGenericMethodDefinition property is false.

If the return type and the number and types of the parameters are known when the method is defined, they can be established using any overload of the TypeBuilder.DefineMethod method that accepts an array of parameter types. However, a generic method can have parameters whose types are specified by one or more of its own generic type parameters, which cannot be defined until after the method has been defined. Use this method to set the parameter types in that case.

If neither the return type nor the parameter types have optional or required custom modifiers, such as IsConst, you can use the SetReturnType and SetParameters methods.

Calling this method replaces the parameters and return type established using the TypeBuilder.DefineMethod method.

The following example shows the use of the SetSignature method.

The example contains source code for a generic class named Sample that has a type parameter T. The class has a field named Field, of type T, and a generic method GM with its own type parameter, U. Method GM creates an instance of Sample, substituting its own type parameter U for the type parameter of Sample, and stores its input parameter in Field.

The code in class Example demonstrates the use of the SetSignature method in emitting generic code. The Main method of class Example creates a dynamic assembly containing a class named Sample, and uses the TypeBuilder.DefineGenericParameters method to make it generic by adding a type parameter named T. A default constructor and a field named Field, of type T, are added to class Sample. A method GM is added, and turned into a generic method using the DefineGenericParameters method. The type parameter of GM is named U. After the type parameter is defined, the signature of GM is added, using the SetSignature method. There is no return type, and no required or custom modifiers, so all the parameters of this method are null except parameterTypes, which sets the type of the only parameter of the method; this is set to the method's type parameter, U. The body of the method creates an instance of the constructed type Sample<U> (Sample(Of U) in Visual Basic), assigns the method's parameter to Field, and then returns the new instance of the constructed type.

The example creates the generic type Sample, and then creates the constructed type Sample<int> (Sample(Of Integer) in Visual Basic). From the constructed type, the static generic method GM<string> (Shared generic method GM(Of String) in Visual Basic) is created and invoked to create an instance of Sample<string>.


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

// Compiling this class produces MSIL similar to that generated by
// the Reflection.Emit code in class Example.
//
public class Sample<T>
{
   public T Data;

   // GM is a Shared method that doesn't use T. It's a factory 
   // method that creates an instance of Sample, substituting U, the
   // type parameter of GM, for T. GM then assigns the argument you
   // pass it to the public Data field of Sample, and returns the
   // new instance of Sample.
   public static Sample<U> GM<U>(U val)
   {
      Sample<U> s = new Sample<U>();
      s.Data = val;
      return s;
   }
}

public class Example
{
   public static void Demo(System.Windows.Controls.TextBlock outputBlock)
   {
      // This code does the same thing as the late-bound code at
      // the end of the Demo method. It calls the shared method GM,
      // using a constructed type. Any type can be substituted for T
      // when you construct this sample; it doesn't have to be the type
      // you're going to specify for U. This is because GM is a Shared
      // method, and U is independent of T.
      Sample<string> sampleOfString = Sample<int>.GM<string>("This is my data.");

      // Display the value of the Data field:
      outputBlock.Text += 
         "The value of the Data field: '" + sampleOfString.Data + "'\n\n";


      AppDomain myDomain = AppDomain.CurrentDomain;
      AssemblyName myAsmName = new AssemblyName("TypeBuilderGetFieldExample");
      AssemblyBuilder myAssembly = 
         myDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.Run);
      ModuleBuilder myModule = myAssembly.DefineDynamicModule(myAsmName.Name);

      // 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 the default constructor. Usually it is not necessary
      // to define the default constructor explicitly, but to instantiate
      // Sample(Of U) you have to have its constructor, and in order to 
      // get that constructor you need to pass the constructor of 
      // Sample(Of T) to the Shared GetConstructor method. The only way
      // to get a reference to the constructor of Sample(Of T) is to use
      // the DefineDefaultConstructor method.
      ConstructorBuilder ctor = 
         myType.DefineDefaultConstructor(MethodAttributes.PrivateScope | 
                  MethodAttributes.Public | MethodAttributes.HideBySig | 
                  MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);

      // Add a field of type T, with the name Data.
      FieldBuilder fieldData = 
         myType.DefineField("Data", 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);
      GenericTypeParameterBuilder[] methodParams = 
                           genMethod.DefineGenericParameters(new string[] {"U"});
      GenericTypeParameterBuilder typeParameterU = methodParams[0];

      // Construct the type Sample(Of U), which is referred to as a 
      // constructed type, by using MakeGenericType.
      Type tSampleOfU = myType.MakeGenericType(typeParameterU);

      // Now add a signature for genMethod, specifying U as the type of
      // the method's only parameter. The return type is Sample(Of U),
      // and there are no custom modifiers.
      genMethod.SetSignature(tSampleOfU, null, null, 
                             new Type[] { typeParameterU }, null, null);

      // Emit a method body for the generic method.
      ILGenerator ilg = genMethod.GetILGenerator();

      // Create a local variable to store the instance of
      // Sample(Of U). This is variable 0 (Ldloc_0, Stloc_0).
      ilg.DeclareLocal(tSampleOfU);


      // To instantiate the constructed type Sample(Of U), you have to 
      // have its constructor. To get that constructor, pass the
      // constructor of the generic type definition, Sample(Of T), to 
      // the Shared TypeBuilder.GetConstructor method. 
      //
      ConstructorInfo ctorOfU = TypeBuilder.GetConstructor(tSampleOfU, ctor);

      // Create an instance of Sample(Of U), and store it in the local 
      // variable.
      ilg.Emit(OpCodes.Newobj, ctorOfU);
      ilg.Emit(OpCodes.Stloc_0);


      // In order to store the value in the field of the new instance 
      // of Sample(Of U), you need a FieldInfo that represents the 
      // Data field of the constructed type. Use TypeBuilder.GetField to 
      // obtain this FieldInfo.
      FieldInfo fieldDataOfU = TypeBuilder.GetField(tSampleOfU, fieldData);

      // To store the value in the instance field, load the Sample(Of U)
      // instance, then load the parameter of genMethod, then call
      // Stfld.
      ilg.Emit(OpCodes.Ldloc_0);
      ilg.Emit(OpCodes.Ldarg_0);
      ilg.Emit(OpCodes.Stfld, fieldDataOfU);

      // Load the instance of Sample(Of U) and return it.
      ilg.Emit(OpCodes.Ldloc_0);
      ilg.Emit(OpCodes.Ret);


      // Create type Sample(Of T).
      Type completed = myType.CreateType();

      // In order to call the Shared method GM, you need a constructed
      // type. You cannot call GM by using the generic type definition.
      // Therefore, create a constructed type. It doesn't matter what
      // type you use for the type parameter. Integer is used here.
      Type constructed = completed.MakeGenericType(typeof(int));

      // Get a generic method definition for Shared generic method GM.
      // This generic method definition is specific to Sample(Of Integer),
      // but that doesn't matter because GM doesn't depend on the type
      // argument of Sample.
      MethodInfo gm = 
         constructed.GetMethod("GM", BindingFlags.Public | BindingFlags.Static);

      // Construct GM(Of String) and display its reflected signature.
      MethodInfo gmConstructed = gm.MakeGenericMethod(typeof(string));
      outputBlock.Text += 
         "The constructed generic method: " + gmConstructed.ToString() + "\n";

      // Finally, invoke the constructed method to create an instance of 
      // Sample(Of String), and then display the contents of the Data 
      // field of the new instance. 
      object obj = gmConstructed.Invoke(null, new object[] { "This is my data." });
      outputBlock.Text += "The value of the Data field: '" + 
         obj.GetType().InvokeMember("Data", 
                                    BindingFlags.GetField, 
                                    Type.DefaultBinder, 
                                    obj, 
                                    null) + "'\n";
   }
}

/* This example produces the following output:

The value of the Data field: 'This is my data.'

The constructed generic method: Sample[System.String] GM[String](System.String)
The value of the Data field: 'This is my data.'
 */


Silverlight

Supported in: 5, 4, 3

For a list of the operating systems and browsers that are supported by Silverlight, see Supported Operating Systems and Browsers.

Community Additions

ADD
Show:
© 2014 Microsoft