ILGenerator.Emit ILGenerator.Emit ILGenerator.Emit Method

Definición

Coloca una instrucción máquina en la secuencia del Lenguaje intermedio de Microsoft (MSIL) para el compilador Just-In-Time (JIT).Puts an instruction onto the Microsoft Intermediate Language (MSIL) stream for the just-in-time (JIT) compiler.

Sobrecargas

Emit(OpCode, Type) Emit(OpCode, Type) Emit(OpCode, Type)

Coloca la instrucción máquina especificada en la secuencia del Lenguaje intermedio de Microsoft (MSIL) seguida del símbolo (token) de metadatos del tipo indicado.Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given type.

Emit(OpCode, String) Emit(OpCode, String) Emit(OpCode, String)

Coloca la instrucción máquina especificada en la secuencia del Lenguaje intermedio de Microsoft (MSIL) seguida del símbolo (token) de metadatos de la cadena indicada.Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given string.

Emit(OpCode, Single) Emit(OpCode, Single) Emit(OpCode, Single)

Coloca la instrucción máquina y el argumento numérico especificados en la secuencia de instrucciones máquina del Lenguaje intermedio de Microsoft (MSIL).Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, SByte) Emit(OpCode, SByte) Emit(OpCode, SByte)

Coloca la instrucción máquina y el argumento de carácter especificados en la secuencia de instrucciones máquina del Lenguaje intermedio de Microsoft (MSIL).Puts the specified instruction and character argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, FieldInfo) Emit(OpCode, FieldInfo) Emit(OpCode, FieldInfo)

Coloca la instrucción máquina y el símbolo (token) de metadatos especificados del campo especificado en la secuencia de instrucciones máquina del Lenguaje intermedio de Microsoft (MSIL).Puts the specified instruction and metadata token for the specified field onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, SignatureHelper) Emit(OpCode, SignatureHelper) Emit(OpCode, SignatureHelper)

Coloca la instrucción máquina especificada y un símbolo (token) de firma en la secuencia de instrucciones máquina del Lenguaje intermedio de Microsoft (MSIL).Puts the specified instruction and a signature token onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, LocalBuilder) Emit(OpCode, LocalBuilder) Emit(OpCode, LocalBuilder)

Coloca la instrucción máquina especificada en la secuencia del Lenguaje intermedio de Microsoft (MSIL) seguida del índice de la variable local indicada.Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the index of the given local variable.

Emit(OpCode, Label[]) Emit(OpCode, Label[]) Emit(OpCode, Label[])

Coloca la instrucción máquina especificada en la secuencia del Lenguaje intermedio de Microsoft (MSIL) y deja espacio para incluir una etiqueta cuando se efectúen correcciones.Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream and leaves space to include a label when fixes are done.

Emit(OpCode, MethodInfo) Emit(OpCode, MethodInfo) Emit(OpCode, MethodInfo)

Coloca la instrucción máquina especificada en la secuencia del Lenguaje intermedio de Microsoft (MSIL) seguida del símbolo (token) de metadatos del método indicado.Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given method.

Emit(OpCode, ConstructorInfo) Emit(OpCode, ConstructorInfo) Emit(OpCode, ConstructorInfo)

Coloca la instrucción máquina y el símbolo (token) de metadatos especificados del constructor especificado en la secuencia de instrucciones máquina del Lenguaje intermedio de Microsoft (MSIL).Puts the specified instruction and metadata token for the specified constructor onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, Int64) Emit(OpCode, Int64) Emit(OpCode, Int64)

Coloca la instrucción máquina y el argumento numérico especificados en la secuencia de instrucciones máquina del Lenguaje intermedio de Microsoft (MSIL).Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, Int32) Emit(OpCode, Int32) Emit(OpCode, Int32)

Coloca la instrucción máquina y el argumento numérico especificados en la secuencia de instrucciones máquina del Lenguaje intermedio de Microsoft (MSIL).Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, Int16) Emit(OpCode, Int16) Emit(OpCode, Int16)

Coloca la instrucción máquina y el argumento numérico especificados en la secuencia de instrucciones máquina del Lenguaje intermedio de Microsoft (MSIL).Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, Double) Emit(OpCode, Double) Emit(OpCode, Double)

Coloca la instrucción máquina y el argumento numérico especificados en la secuencia de instrucciones máquina del Lenguaje intermedio de Microsoft (MSIL).Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, Byte) Emit(OpCode, Byte) Emit(OpCode, Byte)

Coloca la instrucción máquina y el argumento de carácter especificados en la secuencia de instrucciones máquina del Lenguaje intermedio de Microsoft (MSIL).Puts the specified instruction and character argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode) Emit(OpCode) Emit(OpCode)

Coloca la instrucción máquina especificada en la secuencia de instrucciones máquina.Puts the specified instruction onto the stream of instructions.

Emit(OpCode, Label) Emit(OpCode, Label) Emit(OpCode, Label)

Coloca la instrucción máquina especificada en la secuencia del Lenguaje intermedio de Microsoft (MSIL) y deja espacio para incluir una etiqueta cuando se efectúen correcciones.Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream and leaves space to include a label when fixes are done.

Emit(OpCode, Type) Emit(OpCode, Type) Emit(OpCode, Type)

Coloca la instrucción máquina especificada en la secuencia del Lenguaje intermedio de Microsoft (MSIL) seguida del símbolo (token) de metadatos del tipo indicado.Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given type.

public:
 virtual 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
override this.Emit : System.Reflection.Emit.OpCode * Type -> unit

Parámetros

opcode
OpCode OpCode OpCode

Instrucción máquina MSIL que se va a colocar en la secuencia.The MSIL instruction to be put onto the stream.

cls
Type Type Type

Objeto Type.A Type.

Excepciones

Comentarios

Los valores de instrucción se definen en OpCodes la enumeración.The instruction values are defined in the OpCodes enumeration. La ubicación de cls se registra para que se pueda revisar el token si es necesario al almacenar el módulo en un archivo portable ejecutable (PE).The location of cls is recorded so that the token can be patched if necessary when persisting the module to a portable executable (PE) file.

Emit(OpCode, String) Emit(OpCode, String) Emit(OpCode, String)

Coloca la instrucción máquina especificada en la secuencia del Lenguaje intermedio de Microsoft (MSIL) seguida del símbolo (token) de metadatos de la cadena indicada.Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given string.

public:
 virtual void Emit(System::Reflection::Emit::OpCode opcode, System::String ^ str);
public virtual void Emit (System.Reflection.Emit.OpCode opcode, string str);
abstract member Emit : System.Reflection.Emit.OpCode * string -> unit
override this.Emit : System.Reflection.Emit.OpCode * string -> unit

Parámetros

opcode
OpCode OpCode OpCode

La instrucción MSIL que se emiten en la secuencia.The MSIL instruction to be emitted onto the stream.

str
String String String

String que se va a emitir.The String to be emitted.

Comentarios

Los valores de instrucción se definen en OpCodes la enumeración.The instruction values are defined in the OpCodes enumeration. La ubicación de str se registra para futuras correcciones si el módulo se conserva en un archivo portable ejecutable (PE).The location of str is recorded for future fixups if the module is persisted to a portable executable (PE) file.

Emit(OpCode, Single) Emit(OpCode, Single) Emit(OpCode, Single)

Coloca la instrucción máquina y el argumento numérico especificados en la secuencia de instrucciones máquina del Lenguaje intermedio de Microsoft (MSIL).Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

public:
 virtual 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
override this.Emit : System.Reflection.Emit.OpCode * single -> unit

Parámetros

opcode
OpCode OpCode OpCode

Instrucción máquina MSIL que se va a colocar en la secuencia.The MSIL instruction to be put onto the stream.

arg
Single Single Single

Argumento Single que se inserta en la secuencia inmediatamente después de la instrucción máquina.The Single argument pushed onto the stream immediately after the instruction.

Comentarios

Los valores de instrucción se definen en OpCodes la enumeración.The instruction values are defined in the OpCodes enumeration.

Emit(OpCode, SByte) Emit(OpCode, SByte) Emit(OpCode, SByte)

Importante

Esta API no es conforme a CLS.

Coloca la instrucción máquina y el argumento de carácter especificados en la secuencia de instrucciones máquina del Lenguaje intermedio de Microsoft (MSIL).Puts the specified instruction and character argument onto the Microsoft intermediate language (MSIL) stream of instructions.

public:
 void Emit(System::Reflection::Emit::OpCode opcode, System::SByte arg);
[System.CLSCompliant(false)]
public void Emit (System.Reflection.Emit.OpCode opcode, sbyte arg);
member this.Emit : System.Reflection.Emit.OpCode * sbyte -> unit

Parámetros

opcode
OpCode OpCode OpCode

Instrucción máquina MSIL que se va a colocar en la secuencia.The MSIL instruction to be put onto the stream.

arg
SByte SByte SByte

Argumento de carácter insertado en la secuencia inmediatamente después de la instrucción máquina.The character argument pushed onto the stream immediately after the instruction.

Comentarios

Los valores de instrucción se definen en OpCodes la enumeración.The instruction values are defined in the OpCodes enumeration.

Emit(OpCode, FieldInfo) Emit(OpCode, FieldInfo) Emit(OpCode, FieldInfo)

Coloca la instrucción máquina y el símbolo (token) de metadatos especificados del campo especificado en la secuencia de instrucciones máquina del Lenguaje intermedio de Microsoft (MSIL).Puts the specified instruction and metadata token for the specified field onto the Microsoft intermediate language (MSIL) stream of instructions.

public:
 virtual 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
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.FieldInfo -> unit

Parámetros

opcode
OpCode OpCode OpCode

La instrucción MSIL que se emiten en la secuencia.The MSIL instruction to be emitted onto the stream.

field
FieldInfo FieldInfo FieldInfo

FieldInfo que representa un campo.A FieldInfo representing a field.

Comentarios

Los valores de instrucción se definen en OpCodes la enumeración.The instruction values are defined in the OpCodes enumeration. La ubicación de field se registra para que se pueda revisar la secuencia de instrucciones si es necesario al almacenar el módulo en un archivo portable ejecutable (PE).The location of field is recorded so that the instruction stream can be patched if necessary when persisting the module to a portable executable (PE) file.

Emit(OpCode, SignatureHelper) Emit(OpCode, SignatureHelper) Emit(OpCode, SignatureHelper)

Coloca la instrucción máquina especificada y un símbolo (token) de firma en la secuencia de instrucciones máquina del Lenguaje intermedio de Microsoft (MSIL).Puts the specified instruction and a signature token onto the Microsoft intermediate language (MSIL) stream of instructions.

public:
 virtual 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
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.SignatureHelper -> unit

Parámetros

opcode
OpCode OpCode OpCode

La instrucción MSIL que se emiten en la secuencia.The MSIL instruction to be emitted onto the stream.

signature
SignatureHelper SignatureHelper SignatureHelper

Ayuda para crear un símbolo (token) de firma.A helper for constructing a signature token.

Excepciones

Comentarios

Los valores de instrucción se definen en OpCodes la enumeración.The instruction values are defined in the OpCodes enumeration.

Emit(OpCode, LocalBuilder) Emit(OpCode, LocalBuilder) Emit(OpCode, LocalBuilder)

Coloca la instrucción máquina especificada en la secuencia del Lenguaje intermedio de Microsoft (MSIL) seguida del índice de la variable local indicada.Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the index of the given local variable.

public:
 virtual 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
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.LocalBuilder -> unit

Parámetros

opcode
OpCode OpCode OpCode

La instrucción MSIL que se emiten en la secuencia.The MSIL instruction to be emitted onto the stream.

local
LocalBuilder LocalBuilder LocalBuilder

Variable local.A local variable.

Excepciones

El método primario de local no coincide con el método asociado a este ILGenerator.The parent method of the local parameter does not match the method associated with this ILGenerator.

opcode es una instrucción máquina de un solo byte y local representa una variable local con un índice mayor que Byte.MaxValue.opcode is a single-byte instruction, and local represents a local variable with an index greater than Byte.MaxValue.

Comentarios

Los valores de instrucción se definen en OpCodes la enumeración.The instruction values are defined in the OpCodes enumeration.

Emit(OpCode, Label[]) Emit(OpCode, Label[]) Emit(OpCode, Label[])

Coloca la instrucción máquina especificada en la secuencia del Lenguaje intermedio de Microsoft (MSIL) y deja espacio para incluir una etiqueta cuando se efectúen correcciones.Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream and leaves space to include a label when fixes are done.

public:
 virtual void Emit(System::Reflection::Emit::OpCode opcode, cli::array <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
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label[] -> unit

Parámetros

opcode
OpCode OpCode OpCode

La instrucción MSIL que se emiten en la secuencia.The MSIL instruction to be emitted onto the stream.

labels
Label[]

Matriz de objetos de etiqueta en la que se va a realizar la bifurcación desde esta posición.The array of label objects to which to branch from this location. Se utilizan todas las etiquetas.All of the labels will be used.

Excepciones

con es null.con is null. Esta excepción es nueva en .NET Framework 4.NET Framework 4.This exception is new in the .NET Framework 4.NET Framework 4.

Ejemplos

En el ejemplo de código siguiente se muestra la creación de un método dinámico con una tabla de saltos.The code sample below illustrates the creation of a dynamic method with a jump table. La tabla de saltos se genera mediante una Labelmatriz de.The jump table is built using an array of Label.

using namespace System;
using namespace System::Threading;
using namespace System::Reflection;
using namespace System::Reflection::Emit;
Type^ BuildMyType()
{
   AppDomain^ myDomain = Thread::GetDomain();
   AssemblyName^ myAsmName = gcnew AssemblyName;
   myAsmName->Name = "MyDynamicAssembly";
   AssemblyBuilder^ myAsmBuilder = myDomain->DefineDynamicAssembly( myAsmName, AssemblyBuilderAccess::Run );
   ModuleBuilder^ myModBuilder = myAsmBuilder->DefineDynamicModule( "MyJumpTableDemo" );
   TypeBuilder^ myTypeBuilder = myModBuilder->DefineType( "JumpTableDemo", TypeAttributes::Public );
   array<Type^>^temp0 = {int::typeid};
   MethodBuilder^ myMthdBuilder = myTypeBuilder->DefineMethod( "SwitchMe", static_cast<MethodAttributes>(MethodAttributes::Public | MethodAttributes::Static), String::typeid, temp0 );
   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.
   array<Label>^jumpTable = gcnew array<Label>(5);
   jumpTable[ 0 ] = myIL->DefineLabel();
   jumpTable[ 1 ] = myIL->DefineLabel();
   jumpTable[ 2 ] = myIL->DefineLabel();
   jumpTable[ 3 ] = myIL->DefineLabel();
   jumpTable[ 4 ] = 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();
}

int 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, gcnew array<Object^>(0) );
   array<Object^>^temp1 = {theValue};
   Console::WriteLine( "Yes, there {0} today!", myType->InvokeMember( "SwitchMe", BindingFlags::InvokeMethod, nullptr, myInstance, temp1 ) );
}


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
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 'Main

End Class 'DynamicJumpTableDemo

Comentarios

Emite una tabla de modificadores.Emits a switch table.

Los valores de instrucción se definen en OpCodes la enumeración.The instruction values are defined in the OpCodes enumeration.

Las etiquetas se crean DefineLabel mediante y su ubicación dentro de la secuencia se corrige MarkLabelmediante.Labels are created using DefineLabel and their location within the stream is fixed by using 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.If a single-byte instruction is used, the label can represent a jump of at most 127 bytes along the stream. opcodedebe representar una instrucción de bifurcación.opcode must represent a branch instruction. Dado que las bifurcaciones son label instrucciones relativas, se reemplazarán por el desplazamiento correcto para bifurcar durante el proceso de corrección.Because branches are relative instructions, label will be replaced with the correct offset to branch during the fixup process.

Emit(OpCode, MethodInfo) Emit(OpCode, MethodInfo) Emit(OpCode, MethodInfo)

Coloca la instrucción máquina especificada en la secuencia del Lenguaje intermedio de Microsoft (MSIL) seguida del símbolo (token) de metadatos del método indicado.Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given method.

public:
 virtual 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
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.MethodInfo -> unit

Parámetros

opcode
OpCode OpCode OpCode

La instrucción MSIL que se emiten en la secuencia.The MSIL instruction to be emitted onto the stream.

meth
MethodInfo MethodInfo MethodInfo

MethodInfo que representa un método.A MethodInfo representing a method.

Excepciones

meth es un método genérico para el que la propiedad IsGenericMethodDefinition es false.meth is a generic method for which the IsGenericMethodDefinition property is false.

Comentarios

Los valores de instrucción se definen en OpCodes la enumeración.The instruction values are defined in the OpCodes enumeration.

La ubicación de meth se registra para que se pueda revisar la secuencia de instrucciones si es necesario al almacenar el módulo en un archivo portable ejecutable (PE).The location of meth is recorded so that the instruction stream can be patched if necessary when persisting the module to a portable executable (PE) file.

Si meth representa un método genérico, debe ser una definición de método genérico.If meth represents a generic method, it must be a generic method definition. Es decir, su propiedad MethodInfo. IsGenericMethodDefinition debe ser true.That is, its MethodInfo.IsGenericMethodDefinition property must be true.

Emit(OpCode, ConstructorInfo) Emit(OpCode, ConstructorInfo) Emit(OpCode, ConstructorInfo)

Coloca la instrucción máquina y el símbolo (token) de metadatos especificados del constructor especificado en la secuencia de instrucciones máquina del Lenguaje intermedio de Microsoft (MSIL).Puts the specified instruction and metadata token for the specified constructor onto the Microsoft intermediate language (MSIL) stream of instructions.

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
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit

Parámetros

opcode
OpCode OpCode OpCode

La instrucción MSIL que se emiten en la secuencia.The MSIL instruction to be emitted onto the stream.

con
ConstructorInfo ConstructorInfo ConstructorInfo

ConstructorInfo que representa un constructor.A ConstructorInfo representing a constructor.

Excepciones

con es null.con is null. Esta excepción es nueva en .NET Framework 4.NET Framework 4.This exception is new in the .NET Framework 4.NET Framework 4.

Comentarios

Los valores de instrucción se definen en OpCodes la enumeración.The instruction values are defined in the OpCodes enumeration.

La ubicación de con se registra para que se pueda revisar la secuencia de instrucciones si es necesario al almacenar el módulo en un archivo portable ejecutable (PE).The location of con is recorded so that the instruction stream can be patched if necessary when persisting the module to a portable executable (PE) file.

Emit(OpCode, Int64) Emit(OpCode, Int64) Emit(OpCode, Int64)

Coloca la instrucción máquina y el argumento numérico especificados en la secuencia de instrucciones máquina del Lenguaje intermedio de Microsoft (MSIL).Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

public:
 virtual 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
override this.Emit : System.Reflection.Emit.OpCode * int64 -> unit

Parámetros

opcode
OpCode OpCode OpCode

Instrucción máquina MSIL que se va a colocar en la secuencia.The MSIL instruction to be put onto the stream.

arg
Int64 Int64 Int64

Argumento numérico que se inserta en la secuencia inmediatamente después de la instrucción máquina.The numerical argument pushed onto the stream immediately after the instruction.

Comentarios

Los valores de instrucción se definen en OpCodes la enumeración.The instruction values are defined in the OpCodes enumeration.

Emit(OpCode, Int32) Emit(OpCode, Int32) Emit(OpCode, Int32)

Coloca la instrucción máquina y el argumento numérico especificados en la secuencia de instrucciones máquina del Lenguaje intermedio de Microsoft (MSIL).Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

public:
 virtual 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
override this.Emit : System.Reflection.Emit.OpCode * int -> unit

Parámetros

opcode
OpCode OpCode OpCode

Instrucción máquina MSIL que se va a colocar en la secuencia.The MSIL instruction to be put onto the stream.

arg
Int32 Int32 Int32

Argumento numérico que se inserta en la secuencia inmediatamente después de la instrucción máquina.The numerical argument pushed onto the stream immediately after the instruction.

Comentarios

Los valores de instrucción se definen en OpCodes la enumeración.The instruction values are defined in the OpCodes enumeration.

Emit(OpCode, Int16) Emit(OpCode, Int16) Emit(OpCode, Int16)

Coloca la instrucción máquina y el argumento numérico especificados en la secuencia de instrucciones máquina del Lenguaje intermedio de Microsoft (MSIL).Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

public:
 virtual 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
override this.Emit : System.Reflection.Emit.OpCode * int16 -> unit

Parámetros

opcode
OpCode OpCode OpCode

La instrucción MSIL que se emiten en la secuencia.The MSIL instruction to be emitted onto the stream.

arg
Int16 Int16 Int16

Argumento Int que se inserta en la secuencia inmediatamente después de la instrucción máquina.The Int argument pushed onto the stream immediately after the instruction.

Comentarios

Los valores de instrucción se definen en OpCodes la enumeración.The instruction values are defined in the OpCodes enumeration.

Emit(OpCode, Double) Emit(OpCode, Double) Emit(OpCode, Double)

Coloca la instrucción máquina y el argumento numérico especificados en la secuencia de instrucciones máquina del Lenguaje intermedio de Microsoft (MSIL).Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

public:
 virtual 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
override this.Emit : System.Reflection.Emit.OpCode * double -> unit

Parámetros

opcode
OpCode OpCode OpCode

Instrucción máquina MSIL que se va a colocar en la secuencia.The MSIL instruction to be put onto the stream. Se define en la enumeración OpCodes.Defined in the OpCodes enumeration.

arg
Double Double Double

Argumento numérico que se inserta en la secuencia inmediatamente después de la instrucción máquina.The numerical argument pushed onto the stream immediately after the instruction.

Comentarios

Los valores de instrucción se definen en OpCodes la enumeración.The instruction values are defined in the OpCodes enumeration.

Emit(OpCode, Byte) Emit(OpCode, Byte) Emit(OpCode, Byte)

Coloca la instrucción máquina y el argumento de carácter especificados en la secuencia de instrucciones máquina del Lenguaje intermedio de Microsoft (MSIL).Puts the specified instruction and character argument onto the Microsoft intermediate language (MSIL) stream of instructions.

public:
 virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Byte arg);
public virtual void Emit (System.Reflection.Emit.OpCode opcode, byte arg);
abstract member Emit : System.Reflection.Emit.OpCode * byte -> unit
override this.Emit : System.Reflection.Emit.OpCode * byte -> unit

Parámetros

opcode
OpCode OpCode OpCode

Instrucción máquina MSIL que se va a colocar en la secuencia.The MSIL instruction to be put onto the stream.

arg
Byte Byte Byte

Argumento de carácter insertado en la secuencia inmediatamente después de la instrucción máquina.The character argument pushed onto the stream immediately after the instruction.

Comentarios

Los valores de instrucción se definen en OpCodes la enumeración.The instruction values are defined in the OpCodes enumeration.

Emit(OpCode) Emit(OpCode) Emit(OpCode)

Coloca la instrucción máquina especificada en la secuencia de instrucciones máquina.Puts the specified instruction onto the stream of instructions.

public:
 virtual void Emit(System::Reflection::Emit::OpCode opcode);
public virtual void Emit (System.Reflection.Emit.OpCode opcode);
abstract member Emit : System.Reflection.Emit.OpCode -> unit
override this.Emit : System.Reflection.Emit.OpCode -> unit

Parámetros

opcode
OpCode OpCode OpCode

Instrucción máquina del Lenguaje intermedio de Microsoft (MSIL) que se va a colocar en la secuencia.The Microsoft Intermediate Language (MSIL) instruction to be put onto the stream.

Ejemplos

En el ejemplo de código siguiente se muestra Emit el uso de para generar la salida de ILGeneratorMSIL a través de una instancia de.The code sample below demonstrates the use of Emit to generate MSIL output via an instance of ILGenerator.

using namespace System;
using namespace System::Threading;
using namespace System::Reflection;
using namespace System::Reflection::Emit;
Type^ BuildMyType()
{
   AppDomain^ myDomain = Thread::GetDomain();
   AssemblyName^ myAsmName = gcnew AssemblyName;
   myAsmName->Name = "MyDynamicAssembly";
   AssemblyBuilder^ myAsmBuilder = myDomain->DefineDynamicAssembly( myAsmName, AssemblyBuilderAccess::Run );
   ModuleBuilder^ myModBuilder = myAsmBuilder->DefineDynamicModule( "MyJumpTableDemo" );
   TypeBuilder^ myTypeBuilder = myModBuilder->DefineType( "JumpTableDemo", TypeAttributes::Public );
   array<Type^>^temp0 = {int::typeid};
   MethodBuilder^ myMthdBuilder = myTypeBuilder->DefineMethod( "SwitchMe", static_cast<MethodAttributes>(MethodAttributes::Public | MethodAttributes::Static), String::typeid, temp0 );
   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.
   array<Label>^jumpTable = gcnew array<Label>(5);
   jumpTable[ 0 ] = myIL->DefineLabel();
   jumpTable[ 1 ] = myIL->DefineLabel();
   jumpTable[ 2 ] = myIL->DefineLabel();
   jumpTable[ 3 ] = myIL->DefineLabel();
   jumpTable[ 4 ] = 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();
}

int 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, gcnew array<Object^>(0) );
   array<Object^>^temp1 = {theValue};
   Console::WriteLine( "Yes, there {0} today!", myType->InvokeMember( "SwitchMe", BindingFlags::InvokeMethod, nullptr, myInstance, temp1 ) );
}


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
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 'Main

End Class 'DynamicJumpTableDemo

Comentarios

Si el opcode parámetro requiere un argumento, el llamador debe asegurarse de que la longitud del argumento coincide con la longitud del parámetro declarado.If the opcode parameter requires an argument, the caller must ensure that the argument length matches the length of the declared parameter. De lo contrario, los resultados serán impredecibles.Otherwise, results will be unpredictable. Por ejemplo, si la instrucción de emisión 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 en la secuencia de instrucciones.For example, if the Emit instruction requires a 2-byte operand and the caller supplies a 4-byte operand, the runtime will emit two additional bytes to the instruction stream. Estos bytes Nop adicionales serán instrucciones.These extra bytes will be Nop instructions.

Los valores de instrucción se definen OpCodesen.The instruction values are defined in OpCodes.

Emit(OpCode, Label) Emit(OpCode, Label) Emit(OpCode, Label)

Coloca la instrucción máquina especificada en la secuencia del Lenguaje intermedio de Microsoft (MSIL) y deja espacio para incluir una etiqueta cuando se efectúen correcciones.Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream and leaves space to include a label when fixes are done.

public:
 virtual 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
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label -> unit

Parámetros

opcode
OpCode OpCode OpCode

La instrucción MSIL que se emiten en la secuencia.The MSIL instruction to be emitted onto the stream.

label
Label Label Label

Etiqueta a la que se va a saltar desde esta posición.The label to which to branch from this location.

Ejemplos

En el ejemplo de código siguiente se muestra la creación de un método dinámico con una tabla de saltos.The code sample below illustrates the creation of a dynamic method with a jump table. La tabla de saltos se genera mediante una Labelmatriz de.The jump table is built using an array of Label.

using namespace System;
using namespace System::Threading;
using namespace System::Reflection;
using namespace System::Reflection::Emit;
Type^ BuildMyType()
{
   AppDomain^ myDomain = Thread::GetDomain();
   AssemblyName^ myAsmName = gcnew AssemblyName;
   myAsmName->Name = "MyDynamicAssembly";
   AssemblyBuilder^ myAsmBuilder = myDomain->DefineDynamicAssembly( myAsmName, AssemblyBuilderAccess::Run );
   ModuleBuilder^ myModBuilder = myAsmBuilder->DefineDynamicModule( "MyJumpTableDemo" );
   TypeBuilder^ myTypeBuilder = myModBuilder->DefineType( "JumpTableDemo", TypeAttributes::Public );
   array<Type^>^temp0 = {int::typeid};
   MethodBuilder^ myMthdBuilder = myTypeBuilder->DefineMethod( "SwitchMe", static_cast<MethodAttributes>(MethodAttributes::Public | MethodAttributes::Static), String::typeid, temp0 );
   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.
   array<Label>^jumpTable = gcnew array<Label>(5);
   jumpTable[ 0 ] = myIL->DefineLabel();
   jumpTable[ 1 ] = myIL->DefineLabel();
   jumpTable[ 2 ] = myIL->DefineLabel();
   jumpTable[ 3 ] = myIL->DefineLabel();
   jumpTable[ 4 ] = 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();
}

int 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, gcnew array<Object^>(0) );
   array<Object^>^temp1 = {theValue};
   Console::WriteLine( "Yes, there {0} today!", myType->InvokeMember( "SwitchMe", BindingFlags::InvokeMethod, nullptr, myInstance, temp1 ) );
}


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
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 'Main

End Class 'DynamicJumpTableDemo

Comentarios

Los valores de instrucción se definen en OpCodes la enumeración.The instruction values are defined in the OpCodes enumeration.

Las etiquetas se crean DefineLabelmediante y su ubicación dentro de la secuencia se corrige MarkLabelmediante.Labels are created using DefineLabel, and their location within the stream is fixed by using 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.If a single-byte instruction is used, the label can represent a jump of at most 127 bytes along the stream. opcodedebe representar una instrucción de bifurcación.opcode must represent a branch instruction. Dado que las bifurcaciones son label instrucciones relativas, se reemplazarán por el desplazamiento correcto para bifurcar durante el proceso de corrección.Because branches are relative instructions, label will be replaced with the correct offset to branch during the fixup process.

Se aplica a