ILGenerator.Emit Método
Definición
Importante
Parte de la información hace referencia a la versión preliminar del producto, que puede haberse modificado sustancialmente antes de lanzar la versión definitiva. Microsoft no otorga ninguna garantía, explícita o implícita, con respecto a la información proporcionada aquí.
Coloca una instrucción en el flujo de lenguaje intermedio (MSIL) de Microsoft para el compilador Just-In-Time (JIT).
Sobrecargas
| Nombre | Description |
|---|---|
| Emit(OpCode, LocalBuilder) |
Coloca la instrucción especificada en el flujo de lenguaje intermedio (MSIL) Microsoft seguido del índice de la variable local especificada. |
| Emit(OpCode, Type) |
Coloca la instrucción especificada en el flujo de Microsoft lenguaje intermedio (MSIL) seguido del token de metadatos para el tipo especificado. |
| Emit(OpCode, String) |
Coloca la instrucción especificada en el flujo de lenguaje intermedio (MSIL) Microsoft seguido del token de metadatos de la cadena especificada. |
| Emit(OpCode, Single) |
Coloca la instrucción especificada y el argumento numérico en el flujo de instrucciones del lenguaje intermedio (MSIL) de Microsoft. |
| Emit(OpCode, SByte) |
Coloca la instrucción y el argumento de carácter especificados en el flujo de instrucciones del lenguaje intermedio (MSIL) de Microsoft. |
| Emit(OpCode, FieldInfo) |
Coloca la instrucción y el token de metadatos especificados para el campo especificado en el flujo de instrucciones del lenguaje intermedio (MSIL) de Microsoft. |
| Emit(OpCode, SignatureHelper) |
Coloca la instrucción especificada y un token de firma en el flujo de instrucciones de Microsoft lenguaje intermedio (MSIL). |
| Emit(OpCode, Label[]) |
Coloca la instrucción especificada en el flujo de Microsoft lenguaje intermedio (MSIL) y deja espacio para incluir una etiqueta cuando se realizan correcciones. |
| Emit(OpCode, MethodInfo) |
Coloca la instrucción especificada en el flujo de Microsoft lenguaje intermedio (MSIL) seguido del token de metadatos del método especificado. |
| Emit(OpCode, ConstructorInfo) |
Coloca la instrucción y el token de metadatos especificados para el constructor especificado en el flujo de instrucciones del lenguaje intermedio (MSIL) de Microsoft. |
| Emit(OpCode, Int64) |
Coloca la instrucción especificada y el argumento numérico en el flujo de instrucciones del lenguaje intermedio (MSIL) de Microsoft. |
| Emit(OpCode, Int32) |
Coloca la instrucción especificada y el argumento numérico en el flujo de instrucciones del lenguaje intermedio (MSIL) de Microsoft. |
| Emit(OpCode, Int16) |
Coloca la instrucción especificada y el argumento numérico en el flujo de instrucciones del lenguaje intermedio (MSIL) de Microsoft. |
| Emit(OpCode, Double) |
Coloca la instrucción especificada y el argumento numérico en el flujo de instrucciones del lenguaje intermedio (MSIL) de Microsoft. |
| Emit(OpCode, Byte) |
Coloca la instrucción y el argumento de carácter especificados en el flujo de instrucciones del lenguaje intermedio (MSIL) de Microsoft. |
| Emit(OpCode) |
Coloca la instrucción especificada en el flujo de instrucciones. |
| Emit(OpCode, Label) |
Coloca la instrucción especificada en el flujo de Microsoft lenguaje intermedio (MSIL) y deja espacio para incluir una etiqueta cuando se realizan correcciones. |
Emit(OpCode, LocalBuilder)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Coloca la instrucción especificada en el flujo de lenguaje intermedio (MSIL) Microsoft seguido del índice de la variable local especificada.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::LocalBuilder ^ local);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::LocalBuilder ^ local);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.LocalBuilder local);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.LocalBuilder local);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.LocalBuilder -> unit
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.LocalBuilder -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.LocalBuilder -> unit
Public MustOverride Sub Emit (opcode As OpCode, local As LocalBuilder)
Public Overridable Sub Emit (opcode As OpCode, local As LocalBuilder)
Parámetros
- opcode
- OpCode
Instrucción MSIL que se va a emitir en la secuencia.
- local
- LocalBuilder
Variable local.
Excepciones
El método primario del local parámetro no coincide con el método asociado a este ILGenerator.
local es null.
opcode es una instrucción de un solo byte y local representa una variable local con un índice mayor que Byte.MaxValue.
Comentarios
Los valores de instrucción se definen en la OpCodes enumeración .
Se aplica a
Emit(OpCode, Type)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Coloca la instrucción especificada en el flujo de Microsoft lenguaje intermedio (MSIL) seguido del token de metadatos para el tipo especificado.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, Type ^ cls);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, Type ^ cls);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, Type cls);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, Type cls);
abstract member Emit : System.Reflection.Emit.OpCode * Type -> unit
abstract member Emit : System.Reflection.Emit.OpCode * Type -> unit
override this.Emit : System.Reflection.Emit.OpCode * Type -> unit
Public MustOverride Sub Emit (opcode As OpCode, cls As Type)
Public Overridable Sub Emit (opcode As OpCode, cls As Type)
Parámetros
- opcode
- OpCode
Instrucción MSIL que se va a colocar en la secuencia.
- cls
- Type
Un objeto Type.
Excepciones
cls es null.
Comentarios
Los valores de instrucción se definen en la OpCodes enumeración . La ubicación de cls se registra para que el token se pueda revisar si es necesario al conservar el módulo en un archivo ejecutable portátil (PE).
Se aplica a
Emit(OpCode, String)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Coloca la instrucción especificada en el flujo de lenguaje intermedio (MSIL) Microsoft seguido del token de metadatos de la cadena especificada.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::String ^ str);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::String ^ str);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, string str);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, string str);
abstract member Emit : System.Reflection.Emit.OpCode * string -> unit
abstract member Emit : System.Reflection.Emit.OpCode * string -> unit
override this.Emit : System.Reflection.Emit.OpCode * string -> unit
Public MustOverride Sub Emit (opcode As OpCode, str As String)
Public Overridable Sub Emit (opcode As OpCode, str As String)
Parámetros
- opcode
- OpCode
Instrucción MSIL que se va a emitir en la secuencia.
- str
- String
que String se va a emitir.
Comentarios
Los valores de instrucción se definen en la OpCodes enumeración . La ubicación de str se registra para futuras correcciones si el módulo se conserva en un archivo ejecutable portátil (PE).
Se aplica a
Emit(OpCode, Single)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Coloca la instrucción especificada y el argumento numérico en el flujo de instrucciones del lenguaje intermedio (MSIL) de Microsoft.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, float arg);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, float arg);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, float arg);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, float arg);
abstract member Emit : System.Reflection.Emit.OpCode * single -> unit
abstract member Emit : System.Reflection.Emit.OpCode * single -> unit
override this.Emit : System.Reflection.Emit.OpCode * single -> unit
Public MustOverride Sub Emit (opcode As OpCode, arg As Single)
Public Overridable Sub Emit (opcode As OpCode, arg As Single)
Parámetros
- opcode
- OpCode
Instrucción MSIL que se va a colocar en la secuencia.
Comentarios
Los valores de instrucción se definen en la OpCodes enumeración .
Se aplica a
Emit(OpCode, SByte)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Importante
Esta API no es conforme a CLS.
Coloca la instrucción y el argumento de carácter especificados en el flujo de instrucciones del lenguaje intermedio (MSIL) de Microsoft.
public:
void Emit(System::Reflection::Emit::OpCode opcode, System::SByte arg);
[System.CLSCompliant(false)]
public void Emit(System.Reflection.Emit.OpCode opcode, sbyte arg);
[<System.CLSCompliant(false)>]
member this.Emit : System.Reflection.Emit.OpCode * sbyte -> unit
Public Sub Emit (opcode As OpCode, arg As SByte)
Parámetros
- opcode
- OpCode
Instrucción MSIL que se va a colocar en la secuencia.
- arg
- SByte
Argumento de carácter insertado en la secuencia inmediatamente después de la instrucción .
- Atributos
Comentarios
Los valores de instrucción se definen en la OpCodes enumeración .
Se aplica a
Emit(OpCode, FieldInfo)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Coloca la instrucción y el token de metadatos especificados para el campo especificado en el flujo de instrucciones del lenguaje intermedio (MSIL) de Microsoft.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::FieldInfo ^ field);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::FieldInfo ^ field);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.FieldInfo field);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.FieldInfo field);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.FieldInfo -> unit
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.FieldInfo -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.FieldInfo -> unit
Public MustOverride Sub Emit (opcode As OpCode, field As FieldInfo)
Public Overridable Sub Emit (opcode As OpCode, field As FieldInfo)
Parámetros
- opcode
- OpCode
Instrucción MSIL que se va a emitir en la secuencia.
- field
- FieldInfo
que FieldInfo representa un campo.
Comentarios
Los valores de instrucción se definen en la OpCodes enumeración . La ubicación de se registra para que la secuencia de field instrucciones se pueda revisar si es necesario al conservar el módulo en un archivo ejecutable portátil (PE).
Se aplica a
Emit(OpCode, SignatureHelper)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Coloca la instrucción especificada y un token de firma en el flujo de instrucciones de Microsoft lenguaje intermedio (MSIL).
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::SignatureHelper ^ signature);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::SignatureHelper ^ signature);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.SignatureHelper signature);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.SignatureHelper signature);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.SignatureHelper -> unit
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.SignatureHelper -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.SignatureHelper -> unit
Public MustOverride Sub Emit (opcode As OpCode, signature As SignatureHelper)
Public Overridable Sub Emit (opcode As OpCode, signature As SignatureHelper)
Parámetros
- opcode
- OpCode
Instrucción MSIL que se va a emitir en la secuencia.
- signature
- SignatureHelper
Asistente para construir un token de firma.
Excepciones
signature es null.
Comentarios
Los valores de instrucción se definen en la OpCodes enumeración .
Se aplica a
Emit(OpCode, Label[])
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Coloca la instrucción especificada en el flujo de Microsoft lenguaje intermedio (MSIL) y deja espacio para incluir una etiqueta cuando se realizan correcciones.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, cli::array <System::Reflection::Emit::Label> ^ labels);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, cli::array <System::Reflection::Emit::Label> ^ labels);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label[] labels);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label[] labels);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label[] -> unit
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label[] -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label[] -> unit
Public MustOverride Sub Emit (opcode As OpCode, labels As Label())
Public Overridable Sub Emit (opcode As OpCode, labels As Label())
Parámetros
- opcode
- OpCode
Instrucción MSIL que se va a emitir en la secuencia.
- labels
- Label[]
Matriz de objetos de etiqueta a los que se va a bifurcar desde esta ubicación. Se usarán todas las etiquetas.
Ejemplos
En el ejemplo de código siguiente se muestra la creación de un método dinámico con una tabla de saltos. La tabla de saltos se crea mediante una matriz de Label.
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
class DynamicJumpTableDemo
{
public static Type BuildMyType()
{
AppDomain myDomain = Thread.GetDomain();
AssemblyName myAsmName = new AssemblyName();
myAsmName.Name = "MyDynamicAssembly";
AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
myAsmName,
AssemblyBuilderAccess.Run);
ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(
"MyJumpTableDemo");
TypeBuilder myTypeBuilder = myModBuilder.DefineType("JumpTableDemo",
TypeAttributes.Public);
MethodBuilder myMthdBuilder = myTypeBuilder.DefineMethod("SwitchMe",
MethodAttributes.Public |
MethodAttributes.Static,
typeof(string),
new Type[] {typeof(int)});
ILGenerator myIL = myMthdBuilder.GetILGenerator();
Label defaultCase = myIL.DefineLabel();
Label endOfMethod = myIL.DefineLabel();
// We are initializing our jump table. Note that the labels
// will be placed later using the MarkLabel method.
Label[] jumpTable = new Label[] { myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel() };
// arg0, the number we passed, is pushed onto the stack.
// In this case, due to the design of the code sample,
// the value pushed onto the stack happens to match the
// index of the label (in IL terms, the index of the offset
// in the jump table). If this is not the case, such as
// when switching based on non-integer values, rules for the correspondence
// between the possible case values and each index of the offsets
// must be established outside of the ILGenerator.Emit calls,
// much as a compiler would.
myIL.Emit(OpCodes.Ldarg_0);
myIL.Emit(OpCodes.Switch, jumpTable);
// Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase);
// Case arg0 = 0
myIL.MarkLabel(jumpTable[0]);
myIL.Emit(OpCodes.Ldstr, "are no bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 1
myIL.MarkLabel(jumpTable[1]);
myIL.Emit(OpCodes.Ldstr, "is one banana");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 2
myIL.MarkLabel(jumpTable[2]);
myIL.Emit(OpCodes.Ldstr, "are two bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 3
myIL.MarkLabel(jumpTable[3]);
myIL.Emit(OpCodes.Ldstr, "are three bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 4
myIL.MarkLabel(jumpTable[4]);
myIL.Emit(OpCodes.Ldstr, "are four bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Default case
myIL.MarkLabel(defaultCase);
myIL.Emit(OpCodes.Ldstr, "are many bananas");
myIL.MarkLabel(endOfMethod);
myIL.Emit(OpCodes.Ret);
return myTypeBuilder.CreateType();
}
public static void Main()
{
Type myType = BuildMyType();
Console.Write("Enter an integer between 0 and 5: ");
int theValue = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("---");
Object myInstance = Activator.CreateInstance(myType, new object[0]);
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe",
BindingFlags.InvokeMethod,
null,
myInstance,
new object[] {theValue}));
}
}
Imports System.Threading
Imports System.Reflection
Imports System.Reflection.Emit
_
Class DynamicJumpTableDemo
Public Shared Function BuildMyType() As Type
Dim myDomain As AppDomain = Thread.GetDomain()
Dim myAsmName As New AssemblyName()
myAsmName.Name = "MyDynamicAssembly"
Dim myAsmBuilder As AssemblyBuilder = myDomain.DefineDynamicAssembly(myAsmName, _
AssemblyBuilderAccess.Run)
Dim myModBuilder As ModuleBuilder = myAsmBuilder.DefineDynamicModule("MyJumpTableDemo")
Dim myTypeBuilder As TypeBuilder = myModBuilder.DefineType("JumpTableDemo", _
TypeAttributes.Public)
Dim myMthdBuilder As MethodBuilder = myTypeBuilder.DefineMethod("SwitchMe", _
MethodAttributes.Public Or MethodAttributes.Static, _
GetType(String), New Type() {GetType(Integer)})
Dim myIL As ILGenerator = myMthdBuilder.GetILGenerator()
Dim defaultCase As Label = myIL.DefineLabel()
Dim endOfMethod As Label = myIL.DefineLabel()
' We are initializing our jump table. Note that the labels
' will be placed later using the MarkLabel method.
Dim jumpTable() As Label = {myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel()}
' arg0, the number we passed, is pushed onto the stack.
' In this case, due to the design of the code sample,
' the value pushed onto the stack happens to match the
' index of the label (in IL terms, the index of the offset
' in the jump table). If this is not the case, such as
' when switching based on non-integer values, rules for the correspondence
' between the possible case values and each index of the offsets
' must be established outside of the ILGenerator.Emit calls,
' much as a compiler would.
myIL.Emit(OpCodes.Ldarg_0)
myIL.Emit(OpCodes.Switch, jumpTable)
' Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase)
' Case arg0 = 0
myIL.MarkLabel(jumpTable(0))
myIL.Emit(OpCodes.Ldstr, "are no bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 1
myIL.MarkLabel(jumpTable(1))
myIL.Emit(OpCodes.Ldstr, "is one banana")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 2
myIL.MarkLabel(jumpTable(2))
myIL.Emit(OpCodes.Ldstr, "are two bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 3
myIL.MarkLabel(jumpTable(3))
myIL.Emit(OpCodes.Ldstr, "are three bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 4
myIL.MarkLabel(jumpTable(4))
myIL.Emit(OpCodes.Ldstr, "are four bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Default case
myIL.MarkLabel(defaultCase)
myIL.Emit(OpCodes.Ldstr, "are many bananas")
myIL.MarkLabel(endOfMethod)
myIL.Emit(OpCodes.Ret)
Return myTypeBuilder.CreateType()
End Function 'BuildMyType
Public Shared Sub Main()
Dim myType As Type = BuildMyType()
Console.Write("Enter an integer between 0 and 5: ")
Dim theValue As Integer = Convert.ToInt32(Console.ReadLine())
Console.WriteLine("---")
Dim myInstance As [Object] = Activator.CreateInstance(myType, New Object() {})
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe", _
BindingFlags.InvokeMethod, Nothing, _
myInstance, New Object() {theValue}))
End Sub
End Class
Comentarios
Emite una tabla switch.
Los valores de instrucción se definen en la OpCodes enumeración .
Las etiquetas se crean mediante DefineLabel y su ubicación dentro de la secuencia se fija mediante MarkLabel. Si se usa una instrucción de un solo byte, la etiqueta puede representar un salto de como máximo 127 bytes a lo largo de la secuencia.
opcode debe representar una instrucción de rama. Dado que las ramas son instrucciones relativas, label se reemplazarán por el desplazamiento correcto a la rama durante el proceso de corrección.
Se aplica a
Emit(OpCode, MethodInfo)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Coloca la instrucción especificada en el flujo de Microsoft lenguaje intermedio (MSIL) seguido del token de metadatos del método especificado.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::MethodInfo ^ meth);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::MethodInfo ^ meth);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.MethodInfo meth);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.MethodInfo meth);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.MethodInfo -> unit
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.MethodInfo -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.MethodInfo -> unit
Public MustOverride Sub Emit (opcode As OpCode, meth As MethodInfo)
Public Overridable Sub Emit (opcode As OpCode, meth As MethodInfo)
Parámetros
- opcode
- OpCode
Instrucción MSIL que se va a emitir en la secuencia.
- meth
- MethodInfo
que MethodInfo representa un método .
Excepciones
meth es null.
meth es un método genérico para el que la IsGenericMethodDefinition propiedad es false.
Comentarios
Los valores de instrucción se definen en la OpCodes enumeración .
La ubicación de se registra para que la secuencia de meth instrucciones se pueda revisar si es necesario al conservar el módulo en un archivo ejecutable portátil (PE).
Si meth representa un método genérico, debe ser una definición de método genérico. Es decir, su propiedad MethodInfo.IsGenericMethodDefinition debe ser true.
Se aplica a
Emit(OpCode, ConstructorInfo)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Coloca la instrucción y el token de metadatos especificados para el constructor especificado en el flujo de instrucciones del lenguaje intermedio (MSIL) de Microsoft.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::ConstructorInfo ^ con);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::ConstructorInfo ^ con);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.ConstructorInfo con);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.ConstructorInfo con);
[System.Runtime.InteropServices.ComVisible(true)]
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.ConstructorInfo con);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit
[<System.Runtime.InteropServices.ComVisible(true)>]
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit
Public MustOverride Sub Emit (opcode As OpCode, con As ConstructorInfo)
Public Overridable Sub Emit (opcode As OpCode, con As ConstructorInfo)
Parámetros
- opcode
- OpCode
Instrucción MSIL que se va a emitir en la secuencia.
- con
- ConstructorInfo
que ConstructorInfo representa un constructor.
- Atributos
Excepciones
con es null.
Comentarios
Los valores de instrucción se definen en la OpCodes enumeración .
La ubicación de se registra para que la secuencia de con instrucciones se pueda revisar si es necesario al conservar el módulo en un archivo ejecutable portátil (PE).
Se aplica a
Emit(OpCode, Int64)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Coloca la instrucción especificada y el argumento numérico en el flujo de instrucciones del lenguaje intermedio (MSIL) de Microsoft.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, long arg);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, long arg);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, long arg);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, long arg);
abstract member Emit : System.Reflection.Emit.OpCode * int64 -> unit
abstract member Emit : System.Reflection.Emit.OpCode * int64 -> unit
override this.Emit : System.Reflection.Emit.OpCode * int64 -> unit
Public MustOverride Sub Emit (opcode As OpCode, arg As Long)
Public Overridable Sub Emit (opcode As OpCode, arg As Long)
Parámetros
- opcode
- OpCode
Instrucción MSIL que se va a colocar en la secuencia.
- arg
- Int64
Argumento numérico insertado en la secuencia inmediatamente después de la instrucción .
Comentarios
Los valores de instrucción se definen en la OpCodes enumeración .
Se aplica a
Emit(OpCode, Int32)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Coloca la instrucción especificada y el argumento numérico en el flujo de instrucciones del lenguaje intermedio (MSIL) de Microsoft.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, int arg);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, int arg);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, int arg);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, int arg);
abstract member Emit : System.Reflection.Emit.OpCode * int -> unit
abstract member Emit : System.Reflection.Emit.OpCode * int -> unit
override this.Emit : System.Reflection.Emit.OpCode * int -> unit
Public MustOverride Sub Emit (opcode As OpCode, arg As Integer)
Public Overridable Sub Emit (opcode As OpCode, arg As Integer)
Parámetros
- opcode
- OpCode
Instrucción MSIL que se va a colocar en la secuencia.
- arg
- Int32
Argumento numérico insertado en la secuencia inmediatamente después de la instrucción .
Comentarios
Los valores de instrucción se definen en la OpCodes enumeración .
Se aplica a
Emit(OpCode, Int16)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Coloca la instrucción especificada y el argumento numérico en el flujo de instrucciones del lenguaje intermedio (MSIL) de Microsoft.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, short arg);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, short arg);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, short arg);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, short arg);
abstract member Emit : System.Reflection.Emit.OpCode * int16 -> unit
abstract member Emit : System.Reflection.Emit.OpCode * int16 -> unit
override this.Emit : System.Reflection.Emit.OpCode * int16 -> unit
Public MustOverride Sub Emit (opcode As OpCode, arg As Short)
Public Overridable Sub Emit (opcode As OpCode, arg As Short)
Parámetros
- opcode
- OpCode
Instrucción MSIL que se va a emitir en la secuencia.
- arg
- Int16
El Int argumento insertado en la secuencia inmediatamente después de la instrucción .
Comentarios
Los valores de instrucción se definen en la OpCodes enumeración .
Se aplica a
Emit(OpCode, Double)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Coloca la instrucción especificada y el argumento numérico en el flujo de instrucciones del lenguaje intermedio (MSIL) de Microsoft.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, double arg);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, double arg);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, double arg);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, double arg);
abstract member Emit : System.Reflection.Emit.OpCode * double -> unit
abstract member Emit : System.Reflection.Emit.OpCode * double -> unit
override this.Emit : System.Reflection.Emit.OpCode * double -> unit
Public MustOverride Sub Emit (opcode As OpCode, arg As Double)
Public Overridable Sub Emit (opcode As OpCode, arg As Double)
Parámetros
- opcode
- OpCode
Instrucción MSIL que se va a colocar en la secuencia. Definido en la OpCodes enumeración.
- arg
- Double
Argumento numérico insertado en la secuencia inmediatamente después de la instrucción .
Comentarios
Los valores de instrucción se definen en la OpCodes enumeración .
Se aplica a
Emit(OpCode, Byte)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Coloca la instrucción y el argumento de carácter especificados en el flujo de instrucciones del lenguaje intermedio (MSIL) de Microsoft.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Byte arg);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Byte arg);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, byte arg);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, byte arg);
abstract member Emit : System.Reflection.Emit.OpCode * byte -> unit
abstract member Emit : System.Reflection.Emit.OpCode * byte -> unit
override this.Emit : System.Reflection.Emit.OpCode * byte -> unit
Public MustOverride Sub Emit (opcode As OpCode, arg As Byte)
Public Overridable Sub Emit (opcode As OpCode, arg As Byte)
Parámetros
- opcode
- OpCode
Instrucción MSIL que se va a colocar en la secuencia.
- arg
- Byte
Argumento de carácter insertado en la secuencia inmediatamente después de la instrucción .
Comentarios
Los valores de instrucción se definen en la OpCodes enumeración .
Se aplica a
Emit(OpCode)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Coloca la instrucción especificada en el flujo de instrucciones.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode);
public abstract void Emit(System.Reflection.Emit.OpCode opcode);
public virtual void Emit(System.Reflection.Emit.OpCode opcode);
abstract member Emit : System.Reflection.Emit.OpCode -> unit
abstract member Emit : System.Reflection.Emit.OpCode -> unit
override this.Emit : System.Reflection.Emit.OpCode -> unit
Public MustOverride Sub Emit (opcode As OpCode)
Public Overridable Sub Emit (opcode As OpCode)
Parámetros
- opcode
- OpCode
Instrucción Microsoft lenguaje intermedio (MSIL) que se va a colocar en la secuencia.
Ejemplos
En el ejemplo de código siguiente se muestra el uso de para generar la salida de Emit MSIL a través de una instancia de ILGenerator.
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
class DynamicJumpTableDemo
{
public static Type BuildMyType()
{
AppDomain myDomain = Thread.GetDomain();
AssemblyName myAsmName = new AssemblyName();
myAsmName.Name = "MyDynamicAssembly";
AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
myAsmName,
AssemblyBuilderAccess.Run);
ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(
"MyJumpTableDemo");
TypeBuilder myTypeBuilder = myModBuilder.DefineType("JumpTableDemo",
TypeAttributes.Public);
MethodBuilder myMthdBuilder = myTypeBuilder.DefineMethod("SwitchMe",
MethodAttributes.Public |
MethodAttributes.Static,
typeof(string),
new Type[] {typeof(int)});
ILGenerator myIL = myMthdBuilder.GetILGenerator();
Label defaultCase = myIL.DefineLabel();
Label endOfMethod = myIL.DefineLabel();
// We are initializing our jump table. Note that the labels
// will be placed later using the MarkLabel method.
Label[] jumpTable = new Label[] { myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel() };
// arg0, the number we passed, is pushed onto the stack.
// In this case, due to the design of the code sample,
// the value pushed onto the stack happens to match the
// index of the label (in IL terms, the index of the offset
// in the jump table). If this is not the case, such as
// when switching based on non-integer values, rules for the correspondence
// between the possible case values and each index of the offsets
// must be established outside of the ILGenerator.Emit calls,
// much as a compiler would.
myIL.Emit(OpCodes.Ldarg_0);
myIL.Emit(OpCodes.Switch, jumpTable);
// Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase);
// Case arg0 = 0
myIL.MarkLabel(jumpTable[0]);
myIL.Emit(OpCodes.Ldstr, "are no bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 1
myIL.MarkLabel(jumpTable[1]);
myIL.Emit(OpCodes.Ldstr, "is one banana");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 2
myIL.MarkLabel(jumpTable[2]);
myIL.Emit(OpCodes.Ldstr, "are two bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 3
myIL.MarkLabel(jumpTable[3]);
myIL.Emit(OpCodes.Ldstr, "are three bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 4
myIL.MarkLabel(jumpTable[4]);
myIL.Emit(OpCodes.Ldstr, "are four bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Default case
myIL.MarkLabel(defaultCase);
myIL.Emit(OpCodes.Ldstr, "are many bananas");
myIL.MarkLabel(endOfMethod);
myIL.Emit(OpCodes.Ret);
return myTypeBuilder.CreateType();
}
public static void Main()
{
Type myType = BuildMyType();
Console.Write("Enter an integer between 0 and 5: ");
int theValue = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("---");
Object myInstance = Activator.CreateInstance(myType, new object[0]);
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe",
BindingFlags.InvokeMethod,
null,
myInstance,
new object[] {theValue}));
}
}
Imports System.Threading
Imports System.Reflection
Imports System.Reflection.Emit
_
Class DynamicJumpTableDemo
Public Shared Function BuildMyType() As Type
Dim myDomain As AppDomain = Thread.GetDomain()
Dim myAsmName As New AssemblyName()
myAsmName.Name = "MyDynamicAssembly"
Dim myAsmBuilder As AssemblyBuilder = myDomain.DefineDynamicAssembly(myAsmName, _
AssemblyBuilderAccess.Run)
Dim myModBuilder As ModuleBuilder = myAsmBuilder.DefineDynamicModule("MyJumpTableDemo")
Dim myTypeBuilder As TypeBuilder = myModBuilder.DefineType("JumpTableDemo", _
TypeAttributes.Public)
Dim myMthdBuilder As MethodBuilder = myTypeBuilder.DefineMethod("SwitchMe", _
MethodAttributes.Public Or MethodAttributes.Static, _
GetType(String), New Type() {GetType(Integer)})
Dim myIL As ILGenerator = myMthdBuilder.GetILGenerator()
Dim defaultCase As Label = myIL.DefineLabel()
Dim endOfMethod As Label = myIL.DefineLabel()
' We are initializing our jump table. Note that the labels
' will be placed later using the MarkLabel method.
Dim jumpTable() As Label = {myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel()}
' arg0, the number we passed, is pushed onto the stack.
' In this case, due to the design of the code sample,
' the value pushed onto the stack happens to match the
' index of the label (in IL terms, the index of the offset
' in the jump table). If this is not the case, such as
' when switching based on non-integer values, rules for the correspondence
' between the possible case values and each index of the offsets
' must be established outside of the ILGenerator.Emit calls,
' much as a compiler would.
myIL.Emit(OpCodes.Ldarg_0)
myIL.Emit(OpCodes.Switch, jumpTable)
' Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase)
' Case arg0 = 0
myIL.MarkLabel(jumpTable(0))
myIL.Emit(OpCodes.Ldstr, "are no bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 1
myIL.MarkLabel(jumpTable(1))
myIL.Emit(OpCodes.Ldstr, "is one banana")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 2
myIL.MarkLabel(jumpTable(2))
myIL.Emit(OpCodes.Ldstr, "are two bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 3
myIL.MarkLabel(jumpTable(3))
myIL.Emit(OpCodes.Ldstr, "are three bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 4
myIL.MarkLabel(jumpTable(4))
myIL.Emit(OpCodes.Ldstr, "are four bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Default case
myIL.MarkLabel(defaultCase)
myIL.Emit(OpCodes.Ldstr, "are many bananas")
myIL.MarkLabel(endOfMethod)
myIL.Emit(OpCodes.Ret)
Return myTypeBuilder.CreateType()
End Function 'BuildMyType
Public Shared Sub Main()
Dim myType As Type = BuildMyType()
Console.Write("Enter an integer between 0 and 5: ")
Dim theValue As Integer = Convert.ToInt32(Console.ReadLine())
Console.WriteLine("---")
Dim myInstance As [Object] = Activator.CreateInstance(myType, New Object() {})
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe", _
BindingFlags.InvokeMethod, Nothing, _
myInstance, New Object() {theValue}))
End Sub
End Class
Comentarios
Si el opcode parámetro requiere un argumento, el autor de la llamada debe asegurarse de que la longitud del argumento coincide con la longitud del parámetro declarado. De lo contrario, los resultados serán impredecibles. Por ejemplo, si la instrucción Emit requiere un operando de 2 bytes y el autor de la llamada proporciona un operando de 4 bytes, el tiempo de ejecución emitirá dos bytes adicionales a la secuencia de instrucciones. Estos bytes adicionales serán Nop instrucciones.
Los valores de instrucción se definen en OpCodes.
Se aplica a
Emit(OpCode, Label)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Coloca la instrucción especificada en el flujo de Microsoft lenguaje intermedio (MSIL) y deja espacio para incluir una etiqueta cuando se realizan correcciones.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::Label label);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::Label label);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label label);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label label);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label -> unit
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label -> unit
Public MustOverride Sub Emit (opcode As OpCode, label As Label)
Public Overridable Sub Emit (opcode As OpCode, label As Label)
Parámetros
- opcode
- OpCode
Instrucción MSIL que se va a emitir en la secuencia.
- label
- Label
Etiqueta a la que se va a bifurcar desde esta ubicación.
Ejemplos
En el ejemplo de código siguiente se muestra la creación de un método dinámico con una tabla de saltos. La tabla de saltos se crea mediante una matriz de Label.
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
class DynamicJumpTableDemo
{
public static Type BuildMyType()
{
AppDomain myDomain = Thread.GetDomain();
AssemblyName myAsmName = new AssemblyName();
myAsmName.Name = "MyDynamicAssembly";
AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
myAsmName,
AssemblyBuilderAccess.Run);
ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(
"MyJumpTableDemo");
TypeBuilder myTypeBuilder = myModBuilder.DefineType("JumpTableDemo",
TypeAttributes.Public);
MethodBuilder myMthdBuilder = myTypeBuilder.DefineMethod("SwitchMe",
MethodAttributes.Public |
MethodAttributes.Static,
typeof(string),
new Type[] {typeof(int)});
ILGenerator myIL = myMthdBuilder.GetILGenerator();
Label defaultCase = myIL.DefineLabel();
Label endOfMethod = myIL.DefineLabel();
// We are initializing our jump table. Note that the labels
// will be placed later using the MarkLabel method.
Label[] jumpTable = new Label[] { myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel() };
// arg0, the number we passed, is pushed onto the stack.
// In this case, due to the design of the code sample,
// the value pushed onto the stack happens to match the
// index of the label (in IL terms, the index of the offset
// in the jump table). If this is not the case, such as
// when switching based on non-integer values, rules for the correspondence
// between the possible case values and each index of the offsets
// must be established outside of the ILGenerator.Emit calls,
// much as a compiler would.
myIL.Emit(OpCodes.Ldarg_0);
myIL.Emit(OpCodes.Switch, jumpTable);
// Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase);
// Case arg0 = 0
myIL.MarkLabel(jumpTable[0]);
myIL.Emit(OpCodes.Ldstr, "are no bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 1
myIL.MarkLabel(jumpTable[1]);
myIL.Emit(OpCodes.Ldstr, "is one banana");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 2
myIL.MarkLabel(jumpTable[2]);
myIL.Emit(OpCodes.Ldstr, "are two bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 3
myIL.MarkLabel(jumpTable[3]);
myIL.Emit(OpCodes.Ldstr, "are three bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 4
myIL.MarkLabel(jumpTable[4]);
myIL.Emit(OpCodes.Ldstr, "are four bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Default case
myIL.MarkLabel(defaultCase);
myIL.Emit(OpCodes.Ldstr, "are many bananas");
myIL.MarkLabel(endOfMethod);
myIL.Emit(OpCodes.Ret);
return myTypeBuilder.CreateType();
}
public static void Main()
{
Type myType = BuildMyType();
Console.Write("Enter an integer between 0 and 5: ");
int theValue = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("---");
Object myInstance = Activator.CreateInstance(myType, new object[0]);
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe",
BindingFlags.InvokeMethod,
null,
myInstance,
new object[] {theValue}));
}
}
Imports System.Threading
Imports System.Reflection
Imports System.Reflection.Emit
_
Class DynamicJumpTableDemo
Public Shared Function BuildMyType() As Type
Dim myDomain As AppDomain = Thread.GetDomain()
Dim myAsmName As New AssemblyName()
myAsmName.Name = "MyDynamicAssembly"
Dim myAsmBuilder As AssemblyBuilder = myDomain.DefineDynamicAssembly(myAsmName, _
AssemblyBuilderAccess.Run)
Dim myModBuilder As ModuleBuilder = myAsmBuilder.DefineDynamicModule("MyJumpTableDemo")
Dim myTypeBuilder As TypeBuilder = myModBuilder.DefineType("JumpTableDemo", _
TypeAttributes.Public)
Dim myMthdBuilder As MethodBuilder = myTypeBuilder.DefineMethod("SwitchMe", _
MethodAttributes.Public Or MethodAttributes.Static, _
GetType(String), New Type() {GetType(Integer)})
Dim myIL As ILGenerator = myMthdBuilder.GetILGenerator()
Dim defaultCase As Label = myIL.DefineLabel()
Dim endOfMethod As Label = myIL.DefineLabel()
' We are initializing our jump table. Note that the labels
' will be placed later using the MarkLabel method.
Dim jumpTable() As Label = {myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel()}
' arg0, the number we passed, is pushed onto the stack.
' In this case, due to the design of the code sample,
' the value pushed onto the stack happens to match the
' index of the label (in IL terms, the index of the offset
' in the jump table). If this is not the case, such as
' when switching based on non-integer values, rules for the correspondence
' between the possible case values and each index of the offsets
' must be established outside of the ILGenerator.Emit calls,
' much as a compiler would.
myIL.Emit(OpCodes.Ldarg_0)
myIL.Emit(OpCodes.Switch, jumpTable)
' Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase)
' Case arg0 = 0
myIL.MarkLabel(jumpTable(0))
myIL.Emit(OpCodes.Ldstr, "are no bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 1
myIL.MarkLabel(jumpTable(1))
myIL.Emit(OpCodes.Ldstr, "is one banana")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 2
myIL.MarkLabel(jumpTable(2))
myIL.Emit(OpCodes.Ldstr, "are two bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 3
myIL.MarkLabel(jumpTable(3))
myIL.Emit(OpCodes.Ldstr, "are three bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 4
myIL.MarkLabel(jumpTable(4))
myIL.Emit(OpCodes.Ldstr, "are four bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Default case
myIL.MarkLabel(defaultCase)
myIL.Emit(OpCodes.Ldstr, "are many bananas")
myIL.MarkLabel(endOfMethod)
myIL.Emit(OpCodes.Ret)
Return myTypeBuilder.CreateType()
End Function 'BuildMyType
Public Shared Sub Main()
Dim myType As Type = BuildMyType()
Console.Write("Enter an integer between 0 and 5: ")
Dim theValue As Integer = Convert.ToInt32(Console.ReadLine())
Console.WriteLine("---")
Dim myInstance As [Object] = Activator.CreateInstance(myType, New Object() {})
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe", _
BindingFlags.InvokeMethod, Nothing, _
myInstance, New Object() {theValue}))
End Sub
End Class
Comentarios
Los valores de instrucción se definen en la OpCodes enumeración .
Las etiquetas se crean mediante DefineLabely su ubicación dentro de la secuencia se fija mediante MarkLabel. Si se usa una instrucción de un solo byte, la etiqueta puede representar un salto de como máximo 127 bytes a lo largo de la secuencia.
opcode debe representar una instrucción de rama. Dado que las ramas son instrucciones relativas, label se reemplazarán por el desplazamiento correcto a la rama durante el proceso de corrección.