ILGenerator.Emit Método

Definição

Coloca uma instrução no fluxo do MSIL (Microsoft Intermediate Language) para o compilador JIT (Just-In-Time).Puts an instruction onto the Microsoft Intermediate Language (MSIL) stream for the just-in-time (JIT) compiler.

Sobrecargas

Emit(OpCode, Type)

Coloca a instrução especificada no fluxo da MSIL (Microsoft Intermediate Language) seguido pelo token de metadados para o tipo fornecido.Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given type.

Emit(OpCode, String)

Coloca a instrução especificada no fluxo da MSIL (Microsoft Intermediate Language) seguido pelo token de metadados para a cadeia de caracteres fornecida.Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given string.

Emit(OpCode, Single)

Coloca a instrução especificada e o argumento numérico no fluxo de instruções da MSIL (Microsoft Intermediate Language).Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, SByte)

Coloca a instrução especificada e o argumento de caractere no fluxo de instruções da MSIL (Microsoft Intermediate Language).Puts the specified instruction and character argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, FieldInfo)

Coloca a instrução especificada e o token de metadados para o campo especificado no fluxo de instruções da MSIL (Microsoft Intermediate Language).Puts the specified instruction and metadata token for the specified field onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, SignatureHelper)

Coloca a instrução especificada e o token de assinatura no fluxo de instruções da MSIL (Microsoft Intermediate Language).Puts the specified instruction and a signature token onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, LocalBuilder)

Coloca a instrução especificada no fluxo da MSIL (Microsoft Intermediate Language) seguido pelo índice da variável local fornecida.Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the index of the given local variable.

Emit(OpCode, Label[])

Coloca a instrução especificada para o fluxo da MSIL (Microsoft Intermediate Language) e deixa espaço para incluir um rótulo após a realização das correções.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)

Coloca a instrução especificada no fluxo da MSIL (Microsoft Intermediate Language) seguido pelo token de metadados para o método fornecido.Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given method.

Emit(OpCode, ConstructorInfo)

Coloca a instrução especificada e o token de metadados para o construtor especificado no fluxo de instruções da MSIL (Microsoft Intermediate Language).Puts the specified instruction and metadata token for the specified constructor onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, Int64)

Coloca a instrução especificada e o argumento numérico no fluxo de instruções da MSIL (Microsoft Intermediate Language).Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, Int32)

Coloca a instrução especificada e o argumento numérico no fluxo de instruções da MSIL (Microsoft Intermediate Language).Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, Int16)

Coloca a instrução especificada e o argumento numérico no fluxo de instruções da MSIL (Microsoft Intermediate Language).Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, Double)

Coloca a instrução especificada e o argumento numérico no fluxo de instruções da MSIL (Microsoft Intermediate Language).Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, Byte)

Coloca a instrução especificada e o argumento de caractere no fluxo de instruções da MSIL (Microsoft Intermediate Language).Puts the specified instruction and character argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode)

Coloca a instrução especificada no fluxo de instruções.Puts the specified instruction onto the stream of instructions.

Emit(OpCode, Label)

Coloca a instrução especificada para o fluxo da MSIL (Microsoft Intermediate Language) e deixa espaço para incluir um rótulo após a realização das correções.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)

Coloca a instrução especificada no fluxo da MSIL (Microsoft Intermediate Language) seguido pelo token de metadados para o tipo fornecido.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
Public Overridable Sub Emit (opcode As OpCode, cls As Type)

Parâmetros

opcode
OpCode

A instrução MSIL a ser colocada no fluxo.The MSIL instruction to be put onto the stream.

cls
Type

Um Type.A Type.

Exceções

cls é null.cls is null.

Comentários

Os valores de instrução são definidos na OpCodes enumeração.The instruction values are defined in the OpCodes enumeration. O local do cls é registrado para que o token possa ser corrigido, se necessário, ao persistir o módulo em um arquivo executável portátil (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.

Aplica-se a

Emit(OpCode, String)

Coloca a instrução especificada no fluxo da MSIL (Microsoft Intermediate Language) seguido pelo token de metadados para a cadeia de caracteres fornecida.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
Public Overridable Sub Emit (opcode As OpCode, str As String)

Parâmetros

opcode
OpCode

A instrução MSIL para ser emitida para o fluxo.The MSIL instruction to be emitted onto the stream.

str
String

O String a ser emitido.The String to be emitted.

Comentários

Os valores de instrução são definidos na OpCodes enumeração.The instruction values are defined in the OpCodes enumeration. O local do str será registrado para correções futuras se o módulo persistir em um arquivo executável portátil (PE).The location of str is recorded for future fixups if the module is persisted to a portable executable (PE) file.

Aplica-se a

Emit(OpCode, Single)

Coloca a instrução especificada e o argumento numérico no fluxo de instruções da MSIL (Microsoft Intermediate Language).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
Public Overridable Sub Emit (opcode As OpCode, arg As Single)

Parâmetros

opcode
OpCode

A instrução MSIL a ser colocada no fluxo.The MSIL instruction to be put onto the stream.

arg
Single

O argumento Single enviado por push para o fluxo imediatamente após a instrução.The Single argument pushed onto the stream immediately after the instruction.

Comentários

Os valores de instrução são definidos na OpCodes enumeração.The instruction values are defined in the OpCodes enumeration.

Aplica-se a

Emit(OpCode, SByte)

Importante

Esta API não está em conformidade com CLS.

Coloca a instrução especificada e o argumento de caractere no fluxo de instruções da MSIL (Microsoft Intermediate Language).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);
[<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

A instrução MSIL a ser colocada no fluxo.The MSIL instruction to be put onto the stream.

arg
SByte

O argumento de caractere enviado por push para o fluxo imediatamente após a instrução.The character argument pushed onto the stream immediately after the instruction.

Atributos

Comentários

Os valores de instrução são definidos na OpCodes enumeração.The instruction values are defined in the OpCodes enumeration.

Aplica-se a

Emit(OpCode, FieldInfo)

Coloca a instrução especificada e o token de metadados para o campo especificado no fluxo de instruções da MSIL (Microsoft Intermediate Language).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
Public Overridable Sub Emit (opcode As OpCode, field As FieldInfo)

Parâmetros

opcode
OpCode

A instrução MSIL para ser emitida para o fluxo.The MSIL instruction to be emitted onto the stream.

field
FieldInfo

Um FieldInfo que representa um campo.A FieldInfo representing a field.

Comentários

Os valores de instrução são definidos na OpCodes enumeração.The instruction values are defined in the OpCodes enumeration. O local do field é registrado para que o fluxo de instrução possa ser corrigido, se necessário, ao persistir o módulo em um arquivo executável portátil (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.

Aplica-se a

Emit(OpCode, SignatureHelper)

Coloca a instrução especificada e o token de assinatura no fluxo de instruções da MSIL (Microsoft Intermediate Language).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
Public Overridable Sub Emit (opcode As OpCode, signature As SignatureHelper)

Parâmetros

opcode
OpCode

A instrução MSIL para ser emitida para o fluxo.The MSIL instruction to be emitted onto the stream.

signature
SignatureHelper

Um auxiliar para construir um token de assinatura.A helper for constructing a signature token.

Exceções

signature é null.signature is null.

Comentários

Os valores de instrução são definidos na OpCodes enumeração.The instruction values are defined in the OpCodes enumeration.

Aplica-se a

Emit(OpCode, LocalBuilder)

Coloca a instrução especificada no fluxo da MSIL (Microsoft Intermediate Language) seguido pelo índice da variável local fornecida.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
Public Overridable Sub Emit (opcode As OpCode, local As LocalBuilder)

Parâmetros

opcode
OpCode

A instrução MSIL para ser emitida para o fluxo.The MSIL instruction to be emitted onto the stream.

local
LocalBuilder

Uma variável local.A local variable.

Exceções

O método pai do parâmetro local não corresponde ao método associado a este ILGenerator.The parent method of the local parameter does not match the method associated with this ILGenerator.

local é null.local is null.

opcode é uma instrução de byte único e local representa uma variável local com um índice maior que Byte.MaxValue.opcode is a single-byte instruction, and local represents a local variable with an index greater than Byte.MaxValue.

Comentários

Os valores de instrução são definidos na OpCodes enumeração.The instruction values are defined in the OpCodes enumeration.

Aplica-se a

Emit(OpCode, Label[])

Coloca a instrução especificada para o fluxo da MSIL (Microsoft Intermediate Language) e deixa espaço para incluir um rótulo após a realização das correções.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
Public Overridable Sub Emit (opcode As OpCode, labels As Label())

Parâmetros

opcode
OpCode

A instrução MSIL para ser emitida para o fluxo.The MSIL instruction to be emitted onto the stream.

labels
Label[]

A matriz de objetos de rótulo para a qual ramificar deste local.The array of label objects to which to branch from this location. Todos os rótulos serão usados.All of the labels will be used.

Exceções

con é null.con is null. Essa exceção é nova no .NET Framework 4.NET Framework 4.This exception is new in the .NET Framework 4.NET Framework 4.

Exemplos

O exemplo de código abaixo ilustra a criação de um método dinâmico com uma tabela de salto.The code sample below illustrates the creation of a dynamic method with a jump table. A tabela de salto é criada usando uma matriz de Label .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.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

Comentários

Emite uma tabela de comutador.Emits a switch table.

Os valores de instrução são definidos na OpCodes enumeração.The instruction values are defined in the OpCodes enumeration.

Os rótulos são criados usando DefineLabel o e seu local dentro do fluxo é corrigido usando MarkLabel .Labels are created using DefineLabel and their location within the stream is fixed by using MarkLabel. Se uma instrução de byte único for usada, o rótulo poderá representar um salto de no máximo 127 bytes ao longo do fluxo.If a single-byte instruction is used, the label can represent a jump of at most 127 bytes along the stream. opcode deve representar uma instrução de ramificação.opcode must represent a branch instruction. Como as ramificações são instruções relativas, label serão substituídas pelo deslocamento correto para Branch durante o processo de correção.Because branches are relative instructions, label will be replaced with the correct offset to branch during the fixup process.

Aplica-se a

Emit(OpCode, MethodInfo)

Coloca a instrução especificada no fluxo da MSIL (Microsoft Intermediate Language) seguido pelo token de metadados para o método fornecido.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
Public Overridable Sub Emit (opcode As OpCode, meth As MethodInfo)

Parâmetros

opcode
OpCode

A instrução MSIL para ser emitida para o fluxo.The MSIL instruction to be emitted onto the stream.

meth
MethodInfo

Um MethodInfo que representa um método.A MethodInfo representing a method.

Exceções

meth é null.meth is null.

meth é um método genérico para o qual a propriedade IsGenericMethodDefinition é false.meth is a generic method for which the IsGenericMethodDefinition property is false.

Comentários

Os valores de instrução são definidos na OpCodes enumeração.The instruction values are defined in the OpCodes enumeration.

O local do meth é registrado para que o fluxo de instrução possa ser corrigido, se necessário, ao persistir o módulo em um arquivo executável portátil (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.

Se meth representa um método genérico, ele deve ser uma definição de método genérico.If meth represents a generic method, it must be a generic method definition. Ou seja, sua propriedade MethodInfo. genericmethoddefinition deve ser true .That is, its MethodInfo.IsGenericMethodDefinition property must be true.

Aplica-se a

Emit(OpCode, ConstructorInfo)

Coloca a instrução especificada e o token de metadados para o construtor especificado no fluxo de instruções da MSIL (Microsoft Intermediate Language).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);
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
[<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 Overridable Sub Emit (opcode As OpCode, con As ConstructorInfo)

Parâmetros

opcode
OpCode

A instrução MSIL para ser emitida para o fluxo.The MSIL instruction to be emitted onto the stream.

con
ConstructorInfo

Um ConstructorInfo que representa um construtor.A ConstructorInfo representing a constructor.

Atributos

Exceções

con é null.con is null. Essa exceção é nova no .NET Framework 4.NET Framework 4.This exception is new in the .NET Framework 4.NET Framework 4.

Comentários

Os valores de instrução são definidos na OpCodes enumeração.The instruction values are defined in the OpCodes enumeration.

O local do con é registrado para que o fluxo de instrução possa ser corrigido, se necessário, ao persistir o módulo em um arquivo executável portátil (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.

Aplica-se a

Emit(OpCode, Int64)

Coloca a instrução especificada e o argumento numérico no fluxo de instruções da MSIL (Microsoft Intermediate Language).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
Public Overridable Sub Emit (opcode As OpCode, arg As Long)

Parâmetros

opcode
OpCode

A instrução MSIL a ser colocada no fluxo.The MSIL instruction to be put onto the stream.

arg
Int64

O argumento numérico enviado por push para o fluxo imediatamente após a instrução.The numerical argument pushed onto the stream immediately after the instruction.

Comentários

Os valores de instrução são definidos na OpCodes enumeração.The instruction values are defined in the OpCodes enumeration.

Aplica-se a

Emit(OpCode, Int32)

Coloca a instrução especificada e o argumento numérico no fluxo de instruções da MSIL (Microsoft Intermediate Language).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
Public Overridable Sub Emit (opcode As OpCode, arg As Integer)

Parâmetros

opcode
OpCode

A instrução MSIL a ser colocada no fluxo.The MSIL instruction to be put onto the stream.

arg
Int32

O argumento numérico enviado por push para o fluxo imediatamente após a instrução.The numerical argument pushed onto the stream immediately after the instruction.

Comentários

Os valores de instrução são definidos na OpCodes enumeração.The instruction values are defined in the OpCodes enumeration.

Aplica-se a

Emit(OpCode, Int16)

Coloca a instrução especificada e o argumento numérico no fluxo de instruções da MSIL (Microsoft Intermediate Language).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
Public Overridable Sub Emit (opcode As OpCode, arg As Short)

Parâmetros

opcode
OpCode

A instrução MSIL para ser emitida para o fluxo.The MSIL instruction to be emitted onto the stream.

arg
Int16

O argumento Int enviado por push para o fluxo imediatamente após a instrução.The Int argument pushed onto the stream immediately after the instruction.

Comentários

Os valores de instrução são definidos na OpCodes enumeração.The instruction values are defined in the OpCodes enumeration.

Aplica-se a

Emit(OpCode, Double)

Coloca a instrução especificada e o argumento numérico no fluxo de instruções da MSIL (Microsoft Intermediate Language).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
Public Overridable Sub Emit (opcode As OpCode, arg As Double)

Parâmetros

opcode
OpCode

A instrução MSIL a ser colocada no fluxo.The MSIL instruction to be put onto the stream. Definido na enumeração OpCodes.Defined in the OpCodes enumeration.

arg
Double

O argumento numérico enviado por push para o fluxo imediatamente após a instrução.The numerical argument pushed onto the stream immediately after the instruction.

Comentários

Os valores de instrução são definidos na OpCodes enumeração.The instruction values are defined in the OpCodes enumeration.

Aplica-se a

Emit(OpCode, Byte)

Coloca a instrução especificada e o argumento de caractere no fluxo de instruções da MSIL (Microsoft Intermediate Language).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
Public Overridable Sub Emit (opcode As OpCode, arg As Byte)

Parâmetros

opcode
OpCode

A instrução MSIL a ser colocada no fluxo.The MSIL instruction to be put onto the stream.

arg
Byte

O argumento de caractere enviado por push para o fluxo imediatamente após a instrução.The character argument pushed onto the stream immediately after the instruction.

Comentários

Os valores de instrução são definidos na OpCodes enumeração.The instruction values are defined in the OpCodes enumeration.

Aplica-se a

Emit(OpCode)

Coloca a instrução especificada no fluxo de instruções.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
Public Overridable Sub Emit (opcode As OpCode)

Parâmetros

opcode
OpCode

A instrução do MSIL (Microsoft Intermediate Language) a ser colocada no fluxo.The Microsoft Intermediate Language (MSIL) instruction to be put onto the stream.

Exemplos

O exemplo de código a seguir demonstra o uso de Emit para gerar a saída do MSIL por meio de uma instância do ILGenerator .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.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

Comentários

Se o opcode parâmetro exigir um argumento, o chamador deverá garantir que o comprimento do argumento corresponda ao comprimento do 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. Caso contrário, os resultados serão imprevisíveis.Otherwise, results will be unpredictable. Por exemplo, se a instrução Emit exigir um operando de 2 bytes e o chamador fornecer um operando de 4 bytes, o tempo de execução emitirá dois bytes adicionais para o fluxo de instrução.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. Esses bytes extras serão Nop instruções.These extra bytes will be Nop instructions.

Os valores de instrução são definidos em OpCodes .The instruction values are defined in OpCodes.

Aplica-se a

Emit(OpCode, Label)

Coloca a instrução especificada para o fluxo da MSIL (Microsoft Intermediate Language) e deixa espaço para incluir um rótulo após a realização das correções.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
Public Overridable Sub Emit (opcode As OpCode, label As Label)

Parâmetros

opcode
OpCode

A instrução MSIL para ser emitida para o fluxo.The MSIL instruction to be emitted onto the stream.

label
Label

O rótulo para o qual ramificar deste local.The label to which to branch from this location.

Exemplos

O exemplo de código abaixo ilustra a criação de um método dinâmico com uma tabela de salto.The code sample below illustrates the creation of a dynamic method with a jump table. A tabela de salto é criada usando uma matriz de Label .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.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

Comentários

Os valores de instrução são definidos na OpCodes enumeração.The instruction values are defined in the OpCodes enumeration.

Os rótulos são criados usando DefineLabel o, e sua localização dentro do fluxo é corrigida usando MarkLabel .Labels are created using DefineLabel, and their location within the stream is fixed by using MarkLabel. Se uma instrução de byte único for usada, o rótulo poderá representar um salto de no máximo 127 bytes ao longo do fluxo.If a single-byte instruction is used, the label can represent a jump of at most 127 bytes along the stream. opcode deve representar uma instrução de ramificação.opcode must represent a branch instruction. Como as ramificações são instruções relativas, label serão substituídas pelo deslocamento correto para Branch durante o processo de correção.Because branches are relative instructions, label will be replaced with the correct offset to branch during the fixup process.

Aplica-se a