ILGenerator Class
Microsoft Silverlight will reach end of support after October 2021. Learn more.
Generates Microsoft intermediate language (MSIL) instructions.
Inheritance Hierarchy
System.Object
System.Reflection.Emit.ILGenerator
Namespace: System.Reflection.Emit
Assembly: mscorlib (in mscorlib.dll)
Syntax
'Declaration
<ClassInterfaceAttribute(ClassInterfaceType.None)> _
<ComVisibleAttribute(True)> _
Public Class ILGenerator
[ClassInterfaceAttribute(ClassInterfaceType.None)]
[ComVisibleAttribute(true)]
public class ILGenerator
The ILGenerator type exposes the following members.
Methods
Name | Description | |
---|---|---|
BeginCatchBlock | Begins a catch block. | |
BeginExceptFilterBlock | Begins an exception block for a filtered exception. | |
BeginExceptionBlock | Begins an exception block for a non-filtered exception. | |
BeginFaultBlock | Begins an exception fault block in the Microsoft intermediate language (MSIL) stream. | |
BeginFinallyBlock | Begins a finally block in the Microsoft intermediate language (MSIL) instruction stream. | |
BeginScope | Begins a lexical scope. | |
DeclareLocal(Type) | Declares a local variable of the specified type. | |
DeclareLocal(Type, Boolean) | Declares a local variable of the specified type, optionally pinning the object referred to by the variable. | |
DefineLabel | Declares a new label. | |
Emit(OpCode) | Puts the specified instruction onto the stream of instructions. | |
Emit(OpCode, Byte) | Puts the specified instruction and character argument onto the Microsoft intermediate language (MSIL) stream of instructions. | |
Emit(OpCode, Double) | Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions. | |
Emit(OpCode, Int16) | Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions. | |
Emit(OpCode, Int32) | Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions. | |
Emit(OpCode, Int64) | Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions. | |
Emit(OpCode, ConstructorInfo) | Puts the specified instruction and metadata token for the specified constructor onto the Microsoft intermediate language (MSIL) stream of instructions. | |
Emit(OpCode, Label) | Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream and leaves space to include a label when fixes are done. | |
Emit(OpCode, array<Label[]) | Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream and leaves space to include a label when fixes are done. | |
Emit(OpCode, LocalBuilder) | Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the index of the given local variable. | |
Emit(OpCode, FieldInfo) | Puts the specified instruction and metadata token for the specified field onto the Microsoft intermediate language (MSIL) stream of instructions. | |
Emit(OpCode, MethodInfo) | Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given method. | |
Emit(OpCode, SByte) | Puts the specified instruction and character argument onto the Microsoft intermediate language (MSIL) stream of instructions. | |
Emit(OpCode, Single) | Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions. | |
Emit(OpCode, String) | Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given string. | |
Emit(OpCode, Type) | Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given type. | |
EmitCall | Puts a call or callvirt instruction onto the Microsoft intermediate language (MSIL) stream to call a varargs method. | |
EmitWriteLine(FieldInfo) | Emits the Microsoft intermediate language (MSIL) necessary to call Console.WriteLine with the given field. | |
EmitWriteLine(LocalBuilder) | Emits the Microsoft intermediate language (MSIL) necessary to call Console.WriteLine with the given local variable. | |
EmitWriteLine(String) | Emits the Microsoft intermediate language (MSIL) to call Console.WriteLine with a string. | |
EndExceptionBlock | Ends an exception block. | |
EndScope | Ends a lexical scope. | |
Equals(Object) | Determines whether the specified Object is equal to the current Object. (Inherited from Object.) | |
Finalize | Allows an object to try to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection. (Inherited from Object.) | |
GetHashCode | Serves as a hash function for a particular type. (Inherited from Object.) | |
GetType | Gets the Type of the current instance. (Inherited from Object.) | |
MarkLabel | Marks the Microsoft intermediate language (MSIL) stream's current position with the given label. | |
MarkSequencePoint | Marks a sequence point in the Microsoft intermediate language (MSIL) stream. | |
MemberwiseClone | Creates a shallow copy of the current Object. (Inherited from Object.) | |
ThrowException | Emits an instruction to throw an exception. | |
ToString | Returns a string that represents the current object. (Inherited from Object.) | |
UsingNamespace | Specifies the namespace to be used in evaluating locals and watches for the current active lexical scope. |
Top
Fields
Name | Description | |
---|---|---|
syncObj | Gets an object that can be used to synchronize access to this object. |
Top
Remarks
ILGenerator is used to generate method bodies for methods and constructors in dynamic assemblies (represented by the MethodBuilder and ConstructorBuilder classes) and for standalone dynamic methods (represented by the DynamicMethod class). To obtain an ILGenerator, use the ConstructorBuilder.GetILGenerator, DynamicMethod.GetILGenerator, and MethodBuilder.GetILGenerator methods.
MSIL is used as input to a just-in-time (JIT) compiler.
Examples
The following example demonstrates the construction of a dynamic method using ILGenerator to emit OpCodes into a MethodBuilder and a ConstructorBuilder.
Note: |
---|
To run this example, see Building Examples That Use a Demo Method and a TextBlock Control. |
Imports System.Reflection
Imports System.Reflection.Emit
Class Example
Public Shared Sub Demo(ByVal outputBlock As System.Windows.Controls.TextBlock)
Dim myDomain As AppDomain = AppDomain.CurrentDomain
Dim myAsmName As New AssemblyName("MyDynamicAssembly")
Dim myAsmBuilder As AssemblyBuilder = _
myDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.Run)
Dim pointModule As ModuleBuilder = _
myAsmBuilder.DefineDynamicModule("PointModule")
Dim pointTypeBld As TypeBuilder = pointModule.DefineType("Point", _
TypeAttributes.Public)
Dim xField As FieldBuilder = pointTypeBld.DefineField("x", _
GetType(Integer), _
FieldAttributes.Public)
Dim yField As FieldBuilder = pointTypeBld.DefineField("y", _
GetType(Integer), _
FieldAttributes.Public)
' Base class and base class constructor.
Dim objType As Type = Type.GetType("System.Object")
Dim objCtor As ConstructorInfo = objType.GetConstructor(New Type() {})
Dim ctorParams() As Type = {GetType(Integer), GetType(Integer)}
Dim pointCtor As ConstructorBuilder = pointTypeBld.DefineConstructor( _
MethodAttributes.Public, _
CallingConventions.Standard, _
ctorParams)
Dim ctorIL As ILGenerator = pointCtor.GetILGenerator()
' Build the constructor. Begin by invoking the base class
' constructor. The zero-index parameter of the constructor
' is the new instance. Store the values of the fields.
ctorIL.Emit(OpCodes.Ldarg_0)
ctorIL.Emit(OpCodes.Call, objCtor)
ctorIL.Emit(OpCodes.Ldarg_0)
ctorIL.Emit(OpCodes.Ldarg_1)
ctorIL.Emit(OpCodes.Stfld, xField)
ctorIL.Emit(OpCodes.Ldarg_0)
ctorIL.Emit(OpCodes.Ldarg_2)
ctorIL.Emit(OpCodes.Stfld, yField)
ctorIL.Emit(OpCodes.Ret)
' Build a method to output some information about the data
' in the dynamic class. This method will have the following
' signature:
' Public Sub WritePoint(ByVal outputBlock As TextBlock)
Dim obType As Type = outputBlock.GetType()
Dim writePtMthd As MethodBuilder = pointTypeBld.DefineMethod("WritePoint", _
MethodAttributes.Public, _
Nothing, _
New Type() { obType })
' To obtain the current text from the text block, and to
' store the updated value, get the "get" and "set" accessors
' for the Text property:
Dim textProp As PropertyInfo = obType.GetProperty("Text")
Dim getter As MethodInfo = textProp.GetGetMethod()
Dim setter As MethodInfo = textProp.GetSetMethod()
' To concatenate two strings, get the static Concat method of
' the String class:
Dim concat2 As MethodInfo = _
GetType(String).GetMethod("Concat", _
BindingFlags.Public Or BindingFlags.Static, _
Type.DefaultBinder, _
New Type() { GetType(String), GetType(String) }, _
Nothing)
' To format the point values, get the String.Format method
' overload that takes a format string and two values, which
' are passed as objects:
' String.Format(String, Object, Object)
Dim sfParams() As Type = { GetType(String), GetType(Object), GetType(Object) }
Dim strFormat As MethodInfo = _
GetType(String).GetMethod("Format", _
BindingFlags.Public Or BindingFlags.Static, _
Type.DefaultBinder, _
sfParams, Nothing)
' The format string.
Dim ptFormat As String = "The value of the Point is: ({0}, {1})" & vbLf
Dim il As ILGenerator = writePtMthd.GetILGenerator()
' At the very end of the method, the TextBlock instance needs
' to be on the execution stack, to call the "set" accessor for
' the Text property. The TextBlock is the argument passed to
' WritePoint; load it onto the stack now.
il.Emit(OpCodes.Ldarg_1)
' The existing value of the TextBlock.Text property must be on
' the stack, too, so load the TextBlock instance again. Then
' call the "get" accessor for the Text property. The second
' TextBlock reference is popped off the stack, and the string
' value is pushed onto the stack.
il.Emit(OpCodes.Ldarg_1)
il.Emit(OpCodes.Callvirt, getter)
' Now load the arguments for the static String.Format method.
' There's no need to load an instance, because this is a static
' method. Instead, load the first argument for String.Format by
' pushing the format string onto the stack.
il.Emit(OpCodes.Ldstr, ptFormat)
' Since the second argument is an object, and it corresponds to
' to the value of an integer field, the integer field must be
' boxed - stored on the heap as an Object. To load the integer
' field, push a reference to the current instance of Point, which
' is always passed as the hidden 0-index parameter of an instance
' method. Load the field, which pops the Point off the stack.
il.Emit(OpCodes.Ldarg_0)
il.Emit(OpCodes.Ldfld, xField)
' Now execute the box opcode, which pops the value of field 'x'
' and pushes a reference to the integer value, boxed as an object.
il.Emit(OpCodes.Box, GetType(Integer))
' Repeat the process for 'y'.
il.Emit(OpCodes.Ldarg_0)
il.Emit(OpCodes.Ldfld, yField)
il.Emit(OpCodes.Box, GetType(Integer))
' All three arguments for String.Format are on the execution
' stack. Call the static method, which pops the three arguments
' off the stack and pushes the return value onto the stack.
il.Emit(OpCodes.Call, strFormat)
' Call the static String.Concat method to concatenate the value
' of the Text property and the formatted string.
il.Emit(OpCodes.Call, concat2)
' The stack now has an instance of TextBlock and the concatenated
' string. Call the "set" accessor, which pops these items off the
' stack and stores the string in the property.
il.Emit(OpCodes.Callvirt, setter)
' There is nothing left on the stack, so it is safe to return
' from the Sub.
il.Emit(OpCodes.Ret)
' Create the type, and then create an instance of the type with
' 'x' and 'y' values of 8 and 19.
Dim ptType As Type = pointTypeBld.CreateType()
Dim ptInstance As Object = Activator.CreateInstance(ptType, _
New Object() { 8, 19 })
' Invoke WritePoint, to display the values.
ptType.InvokeMember("WritePoint", _
BindingFlags.InvokeMethod, _
Type.DefaultBinder, _
ptInstance, _
New Object() {outputBlock})
End Sub
End Class
' This code example produces the following output:
'
'The value of the Point is: (8, 19)
using System;
using System.Reflection;
using System.Reflection.Emit;
class Example
{
public static void Demo(System.Windows.Controls.TextBlock outputBlock)
{
AppDomain myDomain = AppDomain.CurrentDomain;
AssemblyName myAsmName = new AssemblyName("MyDynamicAssembly");
AssemblyBuilder myAsmBuilder =
myDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.Run);
ModuleBuilder pointModule = myAsmBuilder.DefineDynamicModule("PointModule");
TypeBuilder pointTypeBld = pointModule.DefineType("Point", TypeAttributes.Public);
FieldBuilder xField = pointTypeBld.DefineField("x", typeof(int), FieldAttributes.Public);
FieldBuilder yField = pointTypeBld.DefineField("y", typeof(int), FieldAttributes.Public);
// Base class and base class constructor.
Type objType = Type.GetType("System.Object");
ConstructorInfo objCtor = objType.GetConstructor(new Type[] {});
Type[] ctorParams = {typeof(int), typeof(int)};
ConstructorBuilder pointCtor =
pointTypeBld.DefineConstructor(MethodAttributes.Public,
CallingConventions.Standard, ctorParams);
ILGenerator ctorIL = pointCtor.GetILGenerator();
// Build the constructor. Begin by invoking the base class
// constructor. The zero-index parameter of the constructor
// is the new instance. Store the values of the fields.
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Call, objCtor);
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Ldarg_1);
ctorIL.Emit(OpCodes.Stfld, xField);
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Ldarg_2);
ctorIL.Emit(OpCodes.Stfld, yField);
ctorIL.Emit(OpCodes.Ret);
// Build a method to output some information about the data
// in the dynamic class. This method will have the following
// signature:
// public void WritePoint(TextBlock outputBlock)
Type obType = outputBlock.GetType();
MethodBuilder writePtMthd =
pointTypeBld.DefineMethod("WritePoint",
MethodAttributes.Public,
null,
new Type[] { obType });
// To obtain the current text from the text block, and to
// store the updated value, get the "get" and "set" accessors
// for the Text property:
PropertyInfo textProp = obType.GetProperty("Text");
MethodInfo getter = textProp.GetGetMethod();
MethodInfo setter = textProp.GetSetMethod();
// To concatenate two strings, get the static Concat method of
// the String class:
MethodInfo concat2 =
typeof(string).GetMethod("Concat",
BindingFlags.Public | BindingFlags.Static,
Type.DefaultBinder,
new Type[] { typeof(string), typeof(string) },
null);
// To format the point values, get the String.Format method
// overload that takes a format string and two values, which
// are passed as objects:
// String.Format(string, object, object)
Type[] sfParams = { typeof(string), typeof(object), typeof(object) };
MethodInfo strFormat =
typeof(string).GetMethod("Format",
BindingFlags.Public | BindingFlags.Static,
Type.DefaultBinder,
sfParams, null);
// The format string.
string ptFormat = "The value of the Point is: ({0}, {1})\n";
ILGenerator il = writePtMthd.GetILGenerator();
// At the very end of the method, the TextBlock instance needs
// to be on the execution stack, to call the "set" accessor for
// the Text property. The TextBlock is the argument passed to
// WritePoint; load it onto the stack now.
il.Emit(OpCodes.Ldarg_1);
// The existing value of the TextBlock.Text property must be on
// the stack, too, so load the TextBlock instance again. Then
// call the "get" accessor for the Text property. The second
// TextBlock reference is popped off the stack, and the string
// value is pushed onto the stack.
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Callvirt, getter);
// Now load the arguments for the static String.Format method.
// There's no need to load an instance, because this is a static
// method. Instead, load the first argument for String.Format by
// pushing the format string onto the stack.
il.Emit(OpCodes.Ldstr, ptFormat);
// Since the second argument is an object, and it corresponds to
// to the value of an integer field, the integer field must be
// boxed - stored on the heap as an Object. To load the integer
// field, push a reference to the current instance of Point, which
// is always passed as the hidden 0-index parameter of an instance
// method. Load the field, which pops the Point off the stack.
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, xField);
// Now execute the box opcode, which pops the value of field 'x'
// and pushes a reference to the integer value, boxed as an object.
il.Emit(OpCodes.Box, typeof(int));
// Repeat the process for 'y'.
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldfld, yField);
il.Emit(OpCodes.Box, typeof(int));
// All three arguments for String.Format are on the execution
// stack. Call the static method, which pops the three arguments
// off the stack and pushes the return value onto the stack.
il.Emit(OpCodes.Call, strFormat);
// Call the static String.Concat method to concatenate the value
// of the Text property and the formatted string.
il.Emit(OpCodes.Call, concat2);
// The stack now has an instance of TextBlock and the concatenated
// string. Call the "set" accessor, which pops these items off the
// stack and stores the string in the property.
il.Emit(OpCodes.Callvirt, setter);
// There is nothing left on the stack, so it is safe to return
// from the Sub.
il.Emit(OpCodes.Ret);
// Create the type, and then create an instance of the type with
// 'x' and 'y' values of 8 and 19.
Type ptType = pointTypeBld.CreateType();
object ptInstance = Activator.CreateInstance(ptType, new object[] { 8, 19 });
// Invoke WritePoint, to display the values.
ptType.InvokeMember("WritePoint",
BindingFlags.InvokeMethod,
Type.DefaultBinder,
ptInstance,
new object[] { outputBlock });
}
}
/* This code example produces the following output:
The value of the Point is: (8, 19)
*/
Version Information
Silverlight
Supported in: 5, 4, 3
Silverlight for Windows Phone
Supported in: Windows Phone OS 7.1
Platforms
For a list of the operating systems and browsers that are supported by Silverlight, see Supported Operating Systems and Browsers.
Thread Safety
Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.