Sdílet prostřednictvím


ILGenerator.Emit Metoda

Definice

Vloží instrukce do datového proudu jazyka MSIL (Microsoft Intermediate Language) pro kompilátor JIT (just-in-time).

Přetížení

Emit(OpCode, LocalBuilder)

Vloží zadanou instrukci do datového proudu jazyka MSIL (Microsoft Intermediate Language) následovaný indexem dané místní proměnné.

Emit(OpCode, Type)

Vloží zadanou instrukce do datového proudu jazyka MSIL (Microsoft Intermediate Language) následovaný tokenem metadat pro daný typ.

Emit(OpCode, String)

Vloží zadanou instrukci do datového proudu jazyka MSIL (Microsoft Intermediate Language) následovaný tokenem metadat pro daný řetězec.

Emit(OpCode, Single)

Vloží zadanou instrukci a číselný argument do datového proudu instrukcí jazyka MSIL (Microsoft Intermediate Language).

Emit(OpCode, SByte)

Vloží zadaný argument instrukce a znaku do datového proudu instrukcí jazyka MSIL (Microsoft Intermediate Language).

Emit(OpCode, MethodInfo)

Vloží zadanou instrukci do streamu microsoft intermediate language (MSIL) následovaný tokenem metadat pro danou metodu.

Emit(OpCode, SignatureHelper)

Vloží zadanou instrukci a token podpisu do datového proudu instrukcí jazyka MSIL (Microsoft Intermediate Language).

Emit(OpCode, Label[])

Vloží zadanou instrukci do datového proudu jazyka MSIL (Microsoft Intermediate Language) a po dokončení oprav ponechá prostor pro zahrnutí popisku.

Emit(OpCode, FieldInfo)

Vloží zadanou instrukci a token metadat pro zadané pole do datového proudu instrukcí jazyka MSIL (Microsoft Intermediate Language).

Emit(OpCode, ConstructorInfo)

Vloží zadanou instrukci a token metadat pro zadaný konstruktor do datového proudu instrukcí jazyka MSIL (Microsoft Intermediate Language).

Emit(OpCode, Int64)

Vloží zadanou instrukci a číselný argument do datového proudu instrukcí jazyka MSIL (Microsoft Intermediate Language).

Emit(OpCode, Int32)

Vloží zadanou instrukci a číselný argument do datového proudu instrukcí jazyka MSIL (Microsoft Intermediate Language).

Emit(OpCode, Int16)

Vloží zadanou instrukci a číselný argument do datového proudu instrukcí jazyka MSIL (Microsoft Intermediate Language).

Emit(OpCode, Double)

Vloží zadanou instrukci a číselný argument do datového proudu instrukcí jazyka MSIL (Microsoft Intermediate Language).

Emit(OpCode, Byte)

Vloží zadaný argument instrukce a znaku do datového proudu instrukcí jazyka MSIL (Microsoft Intermediate Language).

Emit(OpCode)

Vloží zadanou instrukce do datového proudu instrukcí.

Emit(OpCode, Label)

Vloží zadanou instrukci do datového proudu jazyka MSIL (Microsoft Intermediate Language) a po dokončení oprav ponechá prostor pro zahrnutí popisku.

Emit(OpCode, LocalBuilder)

Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs

Vloží zadanou instrukci do datového proudu jazyka MSIL (Microsoft Intermediate Language) následovaný indexem dané místní proměnné.

public:
 virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::LocalBuilder ^ local);
public:
 abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::LocalBuilder ^ local);
public virtual void Emit (System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.LocalBuilder local);
public abstract 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
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.LocalBuilder -> unit
Public Overridable Sub Emit (opcode As OpCode, local As LocalBuilder)
Public MustOverride Sub Emit (opcode As OpCode, local As LocalBuilder)

Parametry

opcode
OpCode

Instrukce MSIL, která se má vysílat do datového proudu.

local
LocalBuilder

Místní proměnná.

Výjimky

Nadřazená metoda parametru local neodpovídá metodě přidružené k tomuto ILGeneratorparametru .

local je null.

opcode je jednobajtů instrukce a local představuje místní proměnnou s indexem větším než Byte.MaxValue.

Poznámky

Hodnoty instrukce jsou definovány ve výčtu OpCodes .

Platí pro

Emit(OpCode, Type)

Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs

Vloží zadanou instrukce do datového proudu jazyka MSIL (Microsoft Intermediate Language) následovaný tokenem metadat pro daný typ.

public:
 virtual void Emit(System::Reflection::Emit::OpCode opcode, Type ^ cls);
public:
 abstract void Emit(System::Reflection::Emit::OpCode opcode, Type ^ cls);
public virtual void Emit (System.Reflection.Emit.OpCode opcode, Type cls);
public abstract 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
abstract member Emit : System.Reflection.Emit.OpCode * Type -> unit
Public Overridable Sub Emit (opcode As OpCode, cls As Type)
Public MustOverride Sub Emit (opcode As OpCode, cls As Type)

Parametry

opcode
OpCode

Instrukce jazyka MSIL, která se má vložit do datového proudu.

cls
Type

Úloha Type.

Výjimky

cls je null.

Poznámky

Hodnoty instrukce jsou definovány ve výčtu OpCodes . Umístění cls je zaznamenáno, aby se token mohl v případě potřeby opravit při uchování modulu do přenosného spustitelného souboru (PE).

Platí pro

Emit(OpCode, String)

Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs

Vloží zadanou instrukci do datového proudu jazyka MSIL (Microsoft Intermediate Language) následovaný tokenem metadat pro daný řetězec.

public:
 virtual void Emit(System::Reflection::Emit::OpCode opcode, System::String ^ str);
public:
 abstract void Emit(System::Reflection::Emit::OpCode opcode, System::String ^ str);
public virtual void Emit (System.Reflection.Emit.OpCode opcode, string str);
public abstract 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
abstract member Emit : System.Reflection.Emit.OpCode * string -> unit
Public Overridable Sub Emit (opcode As OpCode, str As String)
Public MustOverride Sub Emit (opcode As OpCode, str As String)

Parametry

opcode
OpCode

Instrukce MSIL, která se má vysílat do datového proudu.

str
String

Hodnota String , která se má vygenerovat.

Poznámky

Hodnoty instrukce jsou definovány ve výčtu OpCodes . Umístění str souboru se zaznamená pro budoucí opravy, pokud je modul trvale uložen v přenosném spustitelném souboru (PE).

Platí pro

Emit(OpCode, Single)

Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs

Vloží zadanou instrukci a číselný argument do datového proudu instrukcí jazyka MSIL (Microsoft Intermediate Language).

public:
 virtual void Emit(System::Reflection::Emit::OpCode opcode, float arg);
public:
 abstract void Emit(System::Reflection::Emit::OpCode opcode, float arg);
public virtual void Emit (System.Reflection.Emit.OpCode opcode, float arg);
public abstract 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
abstract member Emit : System.Reflection.Emit.OpCode * single -> unit
Public Overridable Sub Emit (opcode As OpCode, arg As Single)
Public MustOverride Sub Emit (opcode As OpCode, arg As Single)

Parametry

opcode
OpCode

Instrukce jazyka MSIL, která se má vložit do datového proudu.

arg
Single

Argument Single vložený do streamu okamžitě po instrukci.

Poznámky

Hodnoty instrukce jsou definovány ve výčtu OpCodes .

Platí pro

Emit(OpCode, SByte)

Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs

Důležité

Toto rozhraní API neodpovídá specifikaci CLS.

Vloží zadaný argument instrukce a znaku do datového proudu instrukcí jazyka MSIL (Microsoft Intermediate Language).

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)

Parametry

opcode
OpCode

Instrukce jazyka MSIL, která se má vložit do datového proudu.

arg
SByte

Argument znaku nasdílený do datového proudu okamžitě po instrukci.

Atributy

Poznámky

Hodnoty instrukce jsou definovány ve výčtu OpCodes .

Platí pro

Emit(OpCode, MethodInfo)

Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs

Vloží zadanou instrukci do streamu microsoft intermediate language (MSIL) následovaný tokenem metadat pro danou metodu.

public:
 virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::MethodInfo ^ meth);
public:
 abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::MethodInfo ^ meth);
public virtual void Emit (System.Reflection.Emit.OpCode opcode, System.Reflection.MethodInfo meth);
public abstract 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
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.MethodInfo -> unit
Public Overridable Sub Emit (opcode As OpCode, meth As MethodInfo)
Public MustOverride Sub Emit (opcode As OpCode, meth As MethodInfo)

Parametry

opcode
OpCode

Instrukce MSIL, která se má vysílat do datového proudu.

meth
MethodInfo

A MethodInfo představující metodu.

Výjimky

meth je null.

meth je obecná metoda, pro kterou IsGenericMethodDefinition je falsevlastnost .

Poznámky

Hodnoty instrukce jsou definovány ve výčtu OpCodes .

Umístění meth je zaznamenáno tak, aby se instrukční stream mohl v případě potřeby opravit při uchování modulu do přenosného spustitelného souboru (PE).

Pokud meth představuje obecnou metodu, musí se jednat o definici obecné metody. To znamená, že jeho vlastnost MethodInfo.IsGenericMethodDefinition musí být true.

Platí pro

Emit(OpCode, SignatureHelper)

Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs

Vloží zadanou instrukci a token podpisu do datového proudu instrukcí jazyka MSIL (Microsoft Intermediate Language).

public:
 virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::SignatureHelper ^ signature);
public:
 abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::SignatureHelper ^ signature);
public virtual void Emit (System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.SignatureHelper signature);
public abstract 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
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.SignatureHelper -> unit
Public Overridable Sub Emit (opcode As OpCode, signature As SignatureHelper)
Public MustOverride Sub Emit (opcode As OpCode, signature As SignatureHelper)

Parametry

opcode
OpCode

Instrukce MSIL, která se má vysílat do datového proudu.

signature
SignatureHelper

Pomocná rutina pro vytvoření tokenu podpisu.

Výjimky

signature je null.

Poznámky

Hodnoty instrukce jsou definovány ve výčtu OpCodes .

Platí pro

Emit(OpCode, Label[])

Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs

Vloží zadanou instrukci do datového proudu jazyka MSIL (Microsoft Intermediate Language) a po dokončení oprav ponechá prostor pro zahrnutí popisku.

public:
 virtual void Emit(System::Reflection::Emit::OpCode opcode, cli::array <System::Reflection::Emit::Label> ^ labels);
public:
 abstract void Emit(System::Reflection::Emit::OpCode opcode, cli::array <System::Reflection::Emit::Label> ^ labels);
public virtual void Emit (System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label[] labels);
public abstract 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
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label[] -> unit
Public Overridable Sub Emit (opcode As OpCode, labels As Label())
Public MustOverride Sub Emit (opcode As OpCode, labels As Label())

Parametry

opcode
OpCode

Instrukce MSIL, která se má vysílat do datového proudu.

labels
Label[]

Pole objektů popisků, na které se má větvet z tohoto umístění. Použijí se všechny popisky.

Výjimky

con je null. Tato výjimka je v rozhraní .NET Framework 4 nová.

Příklady

Následující ukázka kódu znázorňuje vytvoření dynamické metody s tabulkou jump. Tabulka jump je sestavená pomocí pole 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

Poznámky

Vygeneruje tabulku přepínačů.

Hodnoty instrukce jsou definovány ve výčtu OpCodes .

Popisky se vytvářejí pomocí DefineLabel a jejich umístění ve streamu je opraveno pomocí MarkLabel. Při použití jednobajtů instrukce může popisek představovat skok maximálně 127 bajtů podél datového proudu. opcode musí představovat instrukce větve. Vzhledem k tomu, že větve jsou relativní instrukce, label budou během procesu opravy nahrazeny správným posunem větve.

Platí pro

Emit(OpCode, FieldInfo)

Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs

Vloží zadanou instrukci a token metadat pro zadané pole do datového proudu instrukcí jazyka MSIL (Microsoft Intermediate Language).

public:
 virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::FieldInfo ^ field);
public:
 abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::FieldInfo ^ field);
public virtual void Emit (System.Reflection.Emit.OpCode opcode, System.Reflection.FieldInfo field);
public abstract 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
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.FieldInfo -> unit
Public Overridable Sub Emit (opcode As OpCode, field As FieldInfo)
Public MustOverride Sub Emit (opcode As OpCode, field As FieldInfo)

Parametry

opcode
OpCode

Instrukce MSIL, která se má vysílat do datového proudu.

field
FieldInfo

A FieldInfo představující pole.

Poznámky

Hodnoty instrukce jsou definovány ve výčtu OpCodes . Umístění field je zaznamenáno tak, aby se instrukční stream mohl v případě potřeby opravit při uchování modulu do přenosného spustitelného souboru (PE).

Platí pro

Emit(OpCode, ConstructorInfo)

Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs

Vloží zadanou instrukci a token metadat pro zadaný konstruktor do datového proudu instrukcí jazyka MSIL (Microsoft Intermediate Language).

public:
 virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::ConstructorInfo ^ con);
public:
 abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::ConstructorInfo ^ con);
public virtual void Emit (System.Reflection.Emit.OpCode opcode, System.Reflection.ConstructorInfo con);
public abstract 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
abstract member 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)
Public MustOverride Sub Emit (opcode As OpCode, con As ConstructorInfo)

Parametry

opcode
OpCode

Instrukce MSIL, která se má vysílat do datového proudu.

con
ConstructorInfo

A ConstructorInfo představující konstruktor.

Atributy

Výjimky

con je null. Tato výjimka je v rozhraní .NET Framework 4 nová.

Poznámky

Hodnoty instrukce jsou definovány ve výčtu OpCodes .

Umístění con je zaznamenáno tak, aby se instrukční stream mohl v případě potřeby opravit při uchování modulu do přenosného spustitelného souboru (PE).

Platí pro

Emit(OpCode, Int64)

Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs

Vloží zadanou instrukci a číselný argument do datového proudu instrukcí jazyka MSIL (Microsoft Intermediate Language).

public:
 virtual void Emit(System::Reflection::Emit::OpCode opcode, long arg);
public:
 abstract void Emit(System::Reflection::Emit::OpCode opcode, long arg);
public virtual void Emit (System.Reflection.Emit.OpCode opcode, long arg);
public abstract 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
abstract member Emit : System.Reflection.Emit.OpCode * int64 -> unit
Public Overridable Sub Emit (opcode As OpCode, arg As Long)
Public MustOverride Sub Emit (opcode As OpCode, arg As Long)

Parametry

opcode
OpCode

Instrukce jazyka MSIL, která se má vložit do datového proudu.

arg
Int64

Číselný argument se do streamu vložil hned po instrukci.

Poznámky

Hodnoty instrukce jsou definovány ve výčtu OpCodes .

Platí pro

Emit(OpCode, Int32)

Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs

Vloží zadanou instrukci a číselný argument do datového proudu instrukcí jazyka MSIL (Microsoft Intermediate Language).

public:
 virtual void Emit(System::Reflection::Emit::OpCode opcode, int arg);
public:
 abstract void Emit(System::Reflection::Emit::OpCode opcode, int arg);
public virtual void Emit (System.Reflection.Emit.OpCode opcode, int arg);
public abstract 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
abstract member Emit : System.Reflection.Emit.OpCode * int -> unit
Public Overridable Sub Emit (opcode As OpCode, arg As Integer)
Public MustOverride Sub Emit (opcode As OpCode, arg As Integer)

Parametry

opcode
OpCode

Instrukce jazyka MSIL, která se má vložit do datového proudu.

arg
Int32

Číselný argument se do streamu vložil hned po instrukci.

Poznámky

Hodnoty instrukce jsou definovány ve výčtu OpCodes .

Platí pro

Emit(OpCode, Int16)

Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs

Vloží zadanou instrukci a číselný argument do datového proudu instrukcí jazyka MSIL (Microsoft Intermediate Language).

public:
 virtual void Emit(System::Reflection::Emit::OpCode opcode, short arg);
public:
 abstract void Emit(System::Reflection::Emit::OpCode opcode, short arg);
public virtual void Emit (System.Reflection.Emit.OpCode opcode, short arg);
public abstract 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
abstract member Emit : System.Reflection.Emit.OpCode * int16 -> unit
Public Overridable Sub Emit (opcode As OpCode, arg As Short)
Public MustOverride Sub Emit (opcode As OpCode, arg As Short)

Parametry

opcode
OpCode

Instrukce MSIL, která se má vysílat do datového proudu.

arg
Int16

Argument Int vložený do streamu okamžitě po instrukci.

Poznámky

Hodnoty instrukce jsou definovány ve výčtu OpCodes .

Platí pro

Emit(OpCode, Double)

Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs

Vloží zadanou instrukci a číselný argument do datového proudu instrukcí jazyka MSIL (Microsoft Intermediate Language).

public:
 virtual void Emit(System::Reflection::Emit::OpCode opcode, double arg);
public:
 abstract void Emit(System::Reflection::Emit::OpCode opcode, double arg);
public virtual void Emit (System.Reflection.Emit.OpCode opcode, double arg);
public abstract 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
abstract member Emit : System.Reflection.Emit.OpCode * double -> unit
Public Overridable Sub Emit (opcode As OpCode, arg As Double)
Public MustOverride Sub Emit (opcode As OpCode, arg As Double)

Parametry

opcode
OpCode

Instrukce jazyka MSIL, která se má vložit do datového proudu. Definováno ve výčtu OpCodes .

arg
Double

Číselný argument se do streamu vložil hned po instrukci.

Poznámky

Hodnoty instrukce jsou definovány ve výčtu OpCodes .

Platí pro

Emit(OpCode, Byte)

Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs

Vloží zadaný argument instrukce a znaku do datového proudu instrukcí jazyka MSIL (Microsoft Intermediate Language).

public:
 virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Byte arg);
public:
 abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Byte arg);
public virtual void Emit (System.Reflection.Emit.OpCode opcode, byte arg);
public abstract 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
abstract member Emit : System.Reflection.Emit.OpCode * byte -> unit
Public Overridable Sub Emit (opcode As OpCode, arg As Byte)
Public MustOverride Sub Emit (opcode As OpCode, arg As Byte)

Parametry

opcode
OpCode

Instrukce jazyka MSIL, která se má vložit do datového proudu.

arg
Byte

Argument znaku nasdílený do datového proudu okamžitě po instrukci.

Poznámky

Hodnoty instrukce jsou definovány ve výčtu OpCodes .

Platí pro

Emit(OpCode)

Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs

Vloží zadanou instrukce do datového proudu instrukcí.

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

Parametry

opcode
OpCode

Instrukce jazyka MSIL (Microsoft Intermediate Language), které se mají vložit do datového proudu.

Příklady

Následující ukázka kódu ukazuje použití nástroje k vygenerování výstupu Emit jazyka MSIL prostřednictvím instance nástroje 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

Poznámky

opcode Pokud parametr vyžaduje argument, volající musí zajistit, aby délka argumentu odpovídala délce deklarovaného parametru. V opačném případě budou výsledky nepředvídatelné. Pokud například instrukce Emit vyžaduje 2 bajtový operand a volající poskytne 4 bajtový operand, modul runtime vygeneruje dva další bajty do instrukčního streamu. Tyto nadbytečné bajty budou Nop pokyny.

Instrukční hodnoty jsou definovány v OpCodessouboru .

Platí pro

Emit(OpCode, Label)

Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs
Zdroj:
ILGenerator.cs

Vloží zadanou instrukci do datového proudu jazyka MSIL (Microsoft Intermediate Language) a po dokončení oprav ponechá prostor pro zahrnutí popisku.

public:
 virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::Label label);
public:
 abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::Label label);
public virtual void Emit (System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label label);
public abstract 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
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label -> unit
Public Overridable Sub Emit (opcode As OpCode, label As Label)
Public MustOverride Sub Emit (opcode As OpCode, label As Label)

Parametry

opcode
OpCode

Instrukce MSIL, která se má vysílat do datového proudu.

label
Label

Popisek, na který se má větev z tohoto umístění.

Příklady

Následující ukázka kódu znázorňuje vytvoření dynamické metody s tabulkou jump. Tabulka jump je sestavená pomocí pole 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

Poznámky

Hodnoty instrukce jsou definovány ve výčtu OpCodes .

Popisky se vytvářejí pomocí DefineLabela jejich umístění v rámci streamu je opraveno pomocí MarkLabel. Při použití jednobajtů instrukce může popisek představovat skok maximálně 127 bajtů podél datového proudu. opcode musí představovat instrukce větve. Vzhledem k tomu, že větve jsou relativní instrukce, label budou během procesu opravy nahrazeny správným posunem větve.

Platí pro