MethodBuilder
Class
Definition
Defines and represents a method (or constructor) on a dynamic class.
[System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.None)]
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class MethodBuilder : System.Reflection.MethodInfo, System.Runtime.InteropServices._MethodBuilder
- Inheritance
- Attributes
- Implements
Inherited Members
System.Object
System.Reflection.MemberInfo
System.Reflection.MethodBase
System.Reflection.MethodInfo
Examples
The following example uses the MethodBuilder class to create a method within a dynamic type.
using namespace System;
using namespace System::Reflection;
using namespace System::Reflection::Emit;
void AddMethodDynamically( TypeBuilder^ myTypeBld,
String^ mthdName,
array<Type^>^ mthdParams,
Type^ returnType,
String^ mthdAction )
{
MethodBuilder^ myMthdBld = myTypeBld->DefineMethod( mthdName, static_cast<MethodAttributes>(MethodAttributes::Public | MethodAttributes::Static), returnType, mthdParams );
ILGenerator^ ILOut = myMthdBld->GetILGenerator();
int numParams = mthdParams->Length;
for ( Byte x = 0; x < numParams; x++ )
{
ILOut->Emit( OpCodes::Ldarg_S, x );
}
if ( numParams > 1 )
{
for ( int y = 0; y < (numParams - 1); y++ )
{
if ( mthdAction->Equals( "A" ) )
ILOut->Emit( OpCodes::Add );
else
if ( mthdAction->Equals( "M" ) )
ILOut->Emit( OpCodes::Mul );
else
ILOut->Emit( OpCodes::Add );
}
}
ILOut->Emit( OpCodes::Ret );
};
void main()
{
AppDomain^ myDomain = AppDomain::CurrentDomain;
AssemblyName^ asmName = gcnew AssemblyName;
asmName->Name = "MyDynamicAsm";
AssemblyBuilder^ myAsmBuilder = myDomain->DefineDynamicAssembly( asmName,
AssemblyBuilderAccess::RunAndSave );
ModuleBuilder^ myModule = myAsmBuilder->DefineDynamicModule( "MyDynamicAsm",
"MyDynamicAsm.dll" );
TypeBuilder^ myTypeBld = myModule->DefineType( "MyDynamicType",
TypeAttributes::Public );
// Get info from the user to build the method dynamically.
Console::WriteLine( "Let's build a simple method dynamically!" );
Console::WriteLine( "Please enter a few numbers, separated by spaces." );
String^ inputNums = Console::ReadLine();
Console::Write( "Do you want to [A]dd (default) or [M]ultiply these numbers? " );
String^ myMthdAction = Console::ReadLine()->ToUpper();
Console::Write( "Lastly, what do you want to name your new dynamic method? " );
String^ myMthdName = Console::ReadLine();
// Process inputNums into an array and create a corresponding Type array
int index = 0;
array<String^>^inputNumsList = inputNums->Split();
array<Type^>^myMthdParams = gcnew array<Type^>(inputNumsList->Length);
array<Object^>^inputValsList = gcnew array<Object^>(inputNumsList->Length);
for each (String^ inputNum in inputNumsList)
{
inputValsList[ index ] = Convert::ToInt32( inputNum );
myMthdParams[ index ] = int::typeid;
index++;
}
// Now, call the method building method with the parameters, passing the
// TypeBuilder by reference.
AddMethodDynamically( myTypeBld,
myMthdName,
myMthdParams,
int::typeid,
myMthdAction );
Type^ myType = myTypeBld->CreateType();
Console::WriteLine( "---" );
Console::WriteLine( "The result of {0} the inputted values is: {1}",
((myMthdAction->Equals( "M" )) ? "multiplying" : "adding"),
myType->InvokeMember( myMthdName,
BindingFlags::InvokeMethod | BindingFlags::Public | BindingFlags::Static,
nullptr,
nullptr,
inputValsList ) );
Console::WriteLine( "---" );
// Let's take a look at the method we created.
// If you are interested in seeing the MSIL generated dynamically for the method
// your program generated, change to the directory where you ran the compiled
// code sample and type "ildasm MyDynamicAsm.dll" at the prompt. When the list
// of manifest contents appears, click on "MyDynamicType" and then on the name of
// of the method you provided during execution.
myAsmBuilder->Save( "MyDynamicAsm.dll" );
MethodInfo^ myMthdInfo = myType->GetMethod( myMthdName );
Console::WriteLine( "Your Dynamic Method: {0};", myMthdInfo );
}
using System;
using System.Reflection;
using System.Reflection.Emit;
class DemoMethodBuilder
{
public static void AddMethodDynamically (TypeBuilder myTypeBld,
string mthdName,
Type[] mthdParams,
Type returnType,
string mthdAction)
{
MethodBuilder myMthdBld = myTypeBld.DefineMethod(
mthdName,
MethodAttributes.Public |
MethodAttributes.Static,
returnType,
mthdParams);
ILGenerator ILout = myMthdBld.GetILGenerator();
int numParams = mthdParams.Length;
for (byte x=0; x < numParams; x++)
{
ILout.Emit(OpCodes.Ldarg_S, x);
}
if (numParams > 1)
{
for (int y=0; y<(numParams-1); y++)
{
switch (mthdAction)
{
case "A": ILout.Emit(OpCodes.Add);
break;
case "M": ILout.Emit(OpCodes.Mul);
break;
default: ILout.Emit(OpCodes.Add);
break;
}
}
}
ILout.Emit(OpCodes.Ret);
}
public static void Main()
{
AppDomain myDomain = AppDomain.CurrentDomain;
AssemblyName asmName = new AssemblyName();
asmName.Name = "MyDynamicAsm";
AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
asmName,
AssemblyBuilderAccess.RunAndSave);
ModuleBuilder myModule = myAsmBuilder.DefineDynamicModule("MyDynamicAsm",
"MyDynamicAsm.dll");
TypeBuilder myTypeBld = myModule.DefineType("MyDynamicType",
TypeAttributes.Public);
// Get info from the user to build the method dynamically.
Console.WriteLine("Let's build a simple method dynamically!");
Console.WriteLine("Please enter a few numbers, separated by spaces.");
string inputNums = Console.ReadLine();
Console.Write("Do you want to [A]dd (default) or [M]ultiply these numbers? ");
string myMthdAction = Console.ReadLine().ToUpper();
Console.Write("Lastly, what do you want to name your new dynamic method? ");
string myMthdName = Console.ReadLine();
// Process inputNums into an array and create a corresponding Type array
int index = 0;
string[] inputNumsList = inputNums.Split();
Type[] myMthdParams = new Type[inputNumsList.Length];
object[] inputValsList = new object[inputNumsList.Length];
foreach (string inputNum in inputNumsList)
{
inputValsList[index] = (object)Convert.ToInt32(inputNum);
myMthdParams[index] = typeof(int);
index++;
}
// Now, call the method building method with the parameters, passing the
// TypeBuilder by reference.
AddMethodDynamically(myTypeBld,
myMthdName,
myMthdParams,
typeof(int),
myMthdAction);
Type myType = myTypeBld.CreateType();
Console.WriteLine("---");
Console.WriteLine("The result of {0} the inputted values is: {1}",
((myMthdAction == "M") ? "multiplying" : "adding"),
myType.InvokeMember(myMthdName,
BindingFlags.InvokeMethod | BindingFlags.Public |
BindingFlags.Static,
null,
null,
inputValsList));
Console.WriteLine("---");
// Let's take a look at the method we created.
// If you are interested in seeing the MSIL generated dynamically for the method
// your program generated, change to the directory where you ran the compiled
// code sample and type "ildasm MyDynamicAsm.dll" at the prompt. When the list
// of manifest contents appears, click on "MyDynamicType" and then on the name of
// of the method you provided during execution.
myAsmBuilder.Save("MyDynamicAsm.dll");
MethodInfo myMthdInfo = myType.GetMethod(myMthdName);
Console.WriteLine("Your Dynamic Method: {0};", myMthdInfo.ToString());
}
}
Imports System
Imports System.Reflection
Imports System.Reflection.Emit
Class DemoMethodBuilder
Public Shared Sub AddMethodDynamically(ByVal myTypeBld As TypeBuilder, _
ByVal mthdName As String, _
ByVal mthdParams() As Type, _
ByVal returnType As Type, _
ByVal mthdAction As String)
Dim myMthdBld As MethodBuilder = myTypeBld.DefineMethod(mthdName, _
MethodAttributes.Public Or MethodAttributes.Static, _
returnType, _
mthdParams)
Dim ILout As ILGenerator = myMthdBld.GetILGenerator()
Dim numParams As Integer = mthdParams.Length
Dim x As Byte
For x = 0 To numParams - 1
ILout.Emit(OpCodes.Ldarg_S, x)
Next x
If numParams > 1 Then
Dim y As Integer
For y = 0 To (numParams - 1) - 1
Select Case mthdAction
Case "A"
ILout.Emit(OpCodes.Add)
Case "M"
ILout.Emit(OpCodes.Mul)
Case Else
ILout.Emit(OpCodes.Add)
End Select
Next y
End If
ILout.Emit(OpCodes.Ret)
End Sub
Public Shared Sub Main()
Dim myDomain As AppDomain = AppDomain.CurrentDomain
Dim asmName As New AssemblyName()
asmName.Name = "MyDynamicAsm"
Dim myAsmBuilder As AssemblyBuilder = myDomain.DefineDynamicAssembly(asmName, _
AssemblyBuilderAccess.RunAndSave)
Dim myModule As ModuleBuilder = myAsmBuilder.DefineDynamicModule("MyDynamicAsm", _
"MyDynamicAsm.dll")
Dim myTypeBld As TypeBuilder = myModule.DefineType("MyDynamicType", TypeAttributes.Public)
' Get info from the user to build the method dynamically.
Console.WriteLine("Let's build a simple method dynamically!")
Console.WriteLine("Please enter a few numbers, separated by spaces.")
Dim inputNums As String = Console.ReadLine()
Console.Write("Do you want to [A]dd (default) or [M]ultiply these numbers? ")
Dim myMthdAction As String = Console.ReadLine().ToUpper()
Console.Write("Lastly, what do you want to name your new dynamic method? ")
Dim myMthdName As String = Console.ReadLine()
' Process inputNums into an array and create a corresponding Type array
Dim index As Integer = 0
Dim inputNumsList As String() = inputNums.Split()
Dim myMthdParams(inputNumsList.Length - 1) As Type
Dim inputValsList(inputNumsList.Length - 1) As Object
Dim inputNum As String
For Each inputNum In inputNumsList
inputValsList(index) = CType(Convert.ToInt32(inputNum), Object)
myMthdParams(index) = GetType(Integer)
index += 1
Next inputNum
' Now, call the method building method with the parameters, passing the
' TypeBuilder by reference.
AddMethodDynamically(myTypeBld, myMthdName, myMthdParams, GetType(Integer), myMthdAction)
Dim myType As Type = myTypeBld.CreateType()
Dim description as String
If myMthdAction = "M" Then
description = "multiplying"
Else
description = "adding"
End If
Console.WriteLine("---")
Console.WriteLine("The result of {0} the values is: {1}", _
description, _
myType.InvokeMember(myMthdName, _
BindingFlags.InvokeMethod _
Or BindingFlags.Public _
Or BindingFlags.Static, _
Nothing, _
Nothing, _
inputValsList))
Console.WriteLine("---")
' If you are interested in seeing the MSIL generated dynamically for the method
' your program generated, change to the directory where you ran the compiled
' code sample and type "ildasm MyDynamicAsm.dll" at the prompt. When the list
' of manifest contents appears, click on "MyDynamicType" and then on the name of
' of the method you provided during execution.
myAsmBuilder.Save("MyDynamicAsm.dll")
Dim myMthdInfo As MethodInfo = myType.GetMethod(myMthdName)
Console.WriteLine("Your Dynamic Method: {0};", myMthdInfo.ToString())
End Sub
End Class
Remarks
The MethodBuilder class is used to fully describe a method in Microsoft intermediate language (MSIL), including the name, attributes, signature, and method body. It is used in conjunction with the TypeBuilder class to create classes at runtime.
Global methods and methods as type members
You can use reflection emit to define global methods and to define methods as type members. The APIs that define methods return MethodBuilder objects.
Global methods
A global method is defined by using the ModuleBuilder.DefineGlobalMethod method, which returns a MethodBuilder object.
Global methods must be static. If a dynamic module contains global methods, the ModuleBuilder.CreateGlobalFunctions method must be called before persisting the dynamic module or the containing dynamic assembly because the common language runtime postpones fixing up the dynamic module until all global functions have been defined.
A global native method is defined by using the ModuleBuilder.DefinePInvokeMethod method. Platform invoke (PInvoke) methods must not be declared abstract or virtual. The runtime sets the MethodAttributes attribute for a platform invoke method.
Methods as members of types
A method is defined as a type member by using the TypeBuilder.DefineMethod method, which returns a MethodBuilder object.
The DefineParameter method is used to set the name and parameter attributes of a parameter, or of the return value. The ParameterBuilder object returned by this method represents a parameter or the return value. The ParameterBuilder object can be used to set the marshaling, to set the constant value, and to apply custom attributes.
Attributes
Members of the MethodAttributes enumeration define the precise character of a dynamic method:
Static methods are specified using the MethodAttributes attribute.
Final methods (methods that cannot be overridden) are specified using the MethodAttributes attribute.
Virtual methods are specified using the MethodAttributes attribute.
Abstract methods are specified using the MethodAttributes attribute.
Several attributes determine method visibility. See the description of the MethodAttributes enumeration.
Methods that implement overloaded operators must set the MethodAttributes attribute.
Finalizers must set the MethodAttributes attribute.
Known Issues
Although MethodBuilder is derived from MethodInfo, some of the abstract methods defined in the MethodInfo class are not fully implemented in MethodBuilder. These MethodBuilder methods throw the NotSupportedException. For example the MethodBuilder.Invoke method is not fully implemented. You can reflect on these methods by retrieving the enclosing type using the Type.GetType or Assembly.GetType methods.
Custom modifiers are supported starting with the .NET Framework version 2.0. They are not supported in earlier versions.
Properties
| Attributes |
Retrieves the attributes for this method. |
| CallingConvention |
Returns the calling convention of the method. |
| ContainsGenericParameters |
Not supported for this type. |
| DeclaringType |
Returns the type that declares this method. |
| InitLocals |
Gets or sets a Boolean value that specifies whether the local variables in this method are zero initialized. The default value of this property is |
| IsGenericMethod |
Gets a value indicating whether the method is a generic method. |
| IsGenericMethodDefinition |
Gets a value indicating whether the current MethodBuilder object represents the definition of a generic method. |
| IsSecurityCritical |
Throws a NotSupportedException in all cases. |
| IsSecuritySafeCritical |
Throws a NotSupportedException in all cases. |
| IsSecurityTransparent |
Throws a NotSupportedException in all cases. |
| MethodHandle |
Retrieves the internal handle for the method. Use this handle to access the underlying metadata handle. |
| MethodImplementationFlags | |
| Module |
Gets the module in which the current method is being defined. |
| Name |
Retrieves the name of this method. |
| ReflectedType |
Retrieves the class that was used in reflection to obtain this object. |
| ReturnParameter |
Gets a ParameterInfo object that contains information about the return type of the method, such as whether the return type has custom modifiers. |
| ReturnType |
Gets the return type of the method represented by this MethodBuilder. |
| ReturnTypeCustomAttributes |
Returns the custom attributes of the method's return type. |
| Signature |
Retrieves the signature of the method. |
Methods
| AddDeclarativeSecurity(SecurityAction, PermissionSet) |
Adds declarative security to this method. |
| CreateMethodBody(Byte[], Int32) |
Creates the body of the method using a supplied byte array of Microsoft intermediate language (MSIL) instructions. |
| DefineGenericParameters(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. |
| DefineParameter(Int32, ParameterAttributes, String) |
Sets the parameter attributes and the name of a parameter of this method, or of the return value of this method. Returns a ParameterBuilder that can be used to apply custom attributes. |
| Equals(Object) |
Determines whether the given object is equal to this instance. |
| GetBaseDefinition() |
Return the base implementation for a method. |
| GetCustomAttributes(Type, Boolean) |
Returns the custom attributes identified by the given type. |
| GetCustomAttributes(Boolean) |
Returns all the custom attributes defined for this method. |
| GetGenericArguments() |
Returns an array of GenericTypeParameterBuilder objects that represent the type parameters of the method, if it is generic. |
| GetGenericMethodDefinition() |
Returns this method. |
| GetHashCode() |
Gets the hash code for this method. |
| GetILGenerator() |
Returns an |
| GetILGenerator(Int32) |
Returns an |
| GetMethodImplementationFlags() |
Returns the implementation flags for the method. |
| GetModule() |
Returns a reference to the module that contains this method. |
| GetParameters() |
Returns the parameters of this method. |
| GetToken() |
Returns the |
| Invoke(Object, BindingFlags, Binder, Object[], CultureInfo) |
Dynamically invokes the method reflected by this instance on the given object, passing along the specified parameters, and under the constraints of the given binder. |
| IsDefined(Type, Boolean) |
Checks if the specified custom attribute type is defined. |
| MakeGenericMethod(Type[]) |
Returns a generic method constructed from the current generic method definition using the specified generic type arguments. |
| SetCustomAttribute(ConstructorInfo, Byte[]) |
Sets a custom attribute using a specified custom attribute blob. |
| SetCustomAttribute(CustomAttributeBuilder) |
Sets a custom attribute using a custom attribute builder. |
| SetImplementationFlags(MethodImplAttributes) |
Sets the implementation flags for this method. |
| SetMarshal(UnmanagedMarshal) |
Sets marshaling information for the return type of this method. |
| SetMethodBody(Byte[], Int32, Byte[], IEnumerable<ExceptionHandler>, IEnumerable<Int32>) |
Creates the body of the method by using a specified byte array of Microsoft intermediate language (MSIL) instructions. |
| SetParameters(Type[]) |
Sets the number and types of parameters for a method. |
| SetReturnType(Type) |
Sets the return type of the method. |
| SetSignature(Type, Type[], Type[], Type[], Type[][], Type[][]) |
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. |
| SetSymCustomAttribute(String, Byte[]) |
Set a symbolic custom attribute using a blob. |
| ToString() |
Returns this |
Explicit Interface Implementations
| _MethodBuilder.GetIDsOfNames(Guid, IntPtr, UInt32, UInt32, IntPtr) |
Maps a set of names to a corresponding set of dispatch identifiers. |
| _MethodBuilder.GetTypeInfo(UInt32, UInt32, IntPtr) |
Retrieves the type information for an object, which can then be used to get the type information for an interface. |
| _MethodBuilder.GetTypeInfoCount(UInt32) |
Retrieves the number of type information interfaces that an object provides (either 0 or 1). |
| _MethodBuilder.Invoke(UInt32, Guid, UInt32, Int16, IntPtr, IntPtr, IntPtr, IntPtr) |
Provides access to properties and methods exposed by an object. |