ILGenerator.Emit Metoda
Definice
Důležité
Některé informace platí pro předběžně vydaný produkt, který se může zásadně změnit, než ho výrobce nebo autor vydá. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Umístí instrukce do datového proudu jazyka MSIL (Microsoft Intermediate Language) pro kompilátor JIT (just-in-time).
Přetížení
| Name | Description |
|---|---|
| Emit(OpCode, LocalBuilder) |
Umístí zadanou instrukci do datového proudu Microsoft intermediate language (MSIL) následovaný indexem dané místní proměnné. |
| Emit(OpCode, Type) |
Vloží zadanou instrukci do datového proudu Microsoft intermediate language (MSIL) následovaný tokenem metadat pro daný typ. |
| Emit(OpCode, String) |
Vloží zadanou instrukci do datového proudu Microsoft intermediate language (MSIL) následovaný tokenem metadat pro daný řetězec. |
| Emit(OpCode, Single) |
Vloží zadaný instrukční a číselný argument do Microsoft zprostředkujícího jazyka (MSIL) instrukce. |
| Emit(OpCode, SByte) |
Vloží zadaný instrukční a znakový argument do Microsoft zprostředkujícího jazyka (MSIL) instrukce. |
| Emit(OpCode, FieldInfo) |
Vloží zadaný instrukční token a token metadat pro zadané pole do datového proudu Microsoft zprostředkujícího jazyka (MSIL). |
| Emit(OpCode, SignatureHelper) |
Vloží zadanou instrukci a token podpisu do datového proudu Microsoft zprostředkujícího jazyka (MSIL). |
| Emit(OpCode, Label[]) |
Umístí zadanou instrukci do datového proudu Microsoft zprostředkujícího jazyka (MSIL) a po dokončení oprav ponechá místo na zahrnutí popisku. |
| Emit(OpCode, MethodInfo) |
Vloží zadanou instrukci do datového proudu Microsoft intermediate language (MSIL) následovaný tokenem metadat pro danou metodu. |
| Emit(OpCode, ConstructorInfo) |
Vloží zadaný instrukční token a token metadat pro zadaný konstruktor do datového proudu Microsoft intermediate language (MSIL). |
| Emit(OpCode, Int64) |
Vloží zadaný instrukční a číselný argument do Microsoft zprostředkujícího jazyka (MSIL) instrukce. |
| Emit(OpCode, Int32) |
Vloží zadaný instrukční a číselný argument do Microsoft zprostředkujícího jazyka (MSIL) instrukce. |
| Emit(OpCode, Int16) |
Vloží zadaný instrukční a číselný argument do Microsoft zprostředkujícího jazyka (MSIL) instrukce. |
| Emit(OpCode, Double) |
Vloží zadaný instrukční a číselný argument do Microsoft zprostředkujícího jazyka (MSIL) instrukce. |
| Emit(OpCode, Byte) |
Vloží zadaný instrukční a znakový argument do Microsoft zprostředkujícího jazyka (MSIL) instrukce. |
| Emit(OpCode) |
Umístí zadanou instrukci do datového proudu instrukcí. |
| Emit(OpCode, Label) |
Umístí zadanou instrukci do datového proudu Microsoft zprostředkujícího jazyka (MSIL) a po dokončení oprav ponechá místo na zahrnutí popisku. |
Emit(OpCode, LocalBuilder)
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
Umístí zadanou instrukci do datového proudu Microsoft intermediate language (MSIL) následovaný indexem dané místní proměnné.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::LocalBuilder ^ local);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::LocalBuilder ^ local);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.LocalBuilder local);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.LocalBuilder local);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.LocalBuilder -> unit
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.LocalBuilder -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.LocalBuilder -> unit
Public MustOverride Sub Emit (opcode As OpCode, local As LocalBuilder)
Public Overridable Sub Emit (opcode As OpCode, local As LocalBuilder)
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 local parametru neodpovídá metodě přidružené k tomuto ILGenerator.
local je null.
opcode je instrukce s jedním bajtem a local představuje místní proměnnou s indexem větším než Byte.MaxValue.
Poznámky
Hodnoty instrukcí jsou definovány ve výčtu OpCodes .
Platí pro
Emit(OpCode, Type)
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
Vloží zadanou instrukci do datového proudu Microsoft intermediate language (MSIL) následovaný tokenem metadat pro daný typ.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, Type ^ cls);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, Type ^ cls);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, Type cls);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, Type cls);
abstract member Emit : System.Reflection.Emit.OpCode * Type -> unit
abstract member Emit : System.Reflection.Emit.OpCode * Type -> unit
override this.Emit : System.Reflection.Emit.OpCode * Type -> unit
Public MustOverride Sub Emit (opcode As OpCode, cls As Type)
Public Overridable Sub Emit (opcode As OpCode, cls As Type)
Parametry
- opcode
- OpCode
Instrukce MSIL, která se má umístit do datového proudu.
- cls
- Type
Nějaké Type.
Výjimky
cls je null.
Poznámky
Hodnoty instrukcí jsou definovány ve výčtu OpCodes .
cls Umístění se zaznamená, aby se token mohl v případě potřeby opravit při zachování modulu do přenosného spustitelného souboru (PE).
Platí pro
Emit(OpCode, String)
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
Vloží zadanou instrukci do datového proudu Microsoft intermediate language (MSIL) následovaný tokenem metadat pro daný řetězec.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::String ^ str);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::String ^ str);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, string str);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, string str);
abstract member Emit : System.Reflection.Emit.OpCode * string -> unit
abstract member Emit : System.Reflection.Emit.OpCode * string -> unit
override this.Emit : System.Reflection.Emit.OpCode * string -> unit
Public MustOverride Sub Emit (opcode As OpCode, str As String)
Public Overridable Sub Emit (opcode As OpCode, str As String)
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 instrukcí jsou definovány ve výčtu OpCodes . Umístění str se zaznamená pro budoucí opravu, pokud je modul trvalý v přenosném spustitelném souboru (PE).
Platí pro
Emit(OpCode, Single)
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
Vloží zadaný instrukční a číselný argument do Microsoft zprostředkujícího jazyka (MSIL) instrukce.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, float arg);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, float arg);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, float arg);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, float arg);
abstract member Emit : System.Reflection.Emit.OpCode * single -> unit
abstract member Emit : System.Reflection.Emit.OpCode * single -> unit
override this.Emit : System.Reflection.Emit.OpCode * single -> unit
Public MustOverride Sub Emit (opcode As OpCode, arg As Single)
Public Overridable Sub Emit (opcode As OpCode, arg As Single)
Parametry
- opcode
- OpCode
Instrukce MSIL, která se má umístit do datového proudu.
Poznámky
Hodnoty instrukcí jsou definovány ve výčtu OpCodes .
Platí pro
Emit(OpCode, SByte)
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
Důležité
Toto rozhraní API neodpovídá specifikaci CLS.
Vloží zadaný instrukční a znakový argument do Microsoft zprostředkujícího jazyka (MSIL) instrukce.
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 MSIL, která se má umístit do datového proudu.
- arg
- SByte
Argument znaku se nasdílí do datového proudu bezprostředně po instrukci.
- Atributy
Poznámky
Hodnoty instrukcí jsou definovány ve výčtu OpCodes .
Platí pro
Emit(OpCode, FieldInfo)
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
Vloží zadaný instrukční token a token metadat pro zadané pole do datového proudu Microsoft zprostředkujícího jazyka (MSIL).
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::FieldInfo ^ field);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::FieldInfo ^ field);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.FieldInfo field);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.FieldInfo field);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.FieldInfo -> unit
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.FieldInfo -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.FieldInfo -> unit
Public MustOverride Sub Emit (opcode As OpCode, field As FieldInfo)
Public Overridable Sub Emit (opcode As OpCode, field As FieldInfo)
Parametry
- opcode
- OpCode
Instrukce MSIL, která se má vysílat do datového proudu.
- field
- FieldInfo
Představuje FieldInfo pole.
Poznámky
Hodnoty instrukcí jsou definovány ve výčtu OpCodes .
field Umístění je zaznamenáno tak, aby datový proud instrukce bylo možné v případě potřeby opravit při zachování modulu do přenosného spustitelného souboru (PE).
Platí pro
Emit(OpCode, SignatureHelper)
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
Vloží zadanou instrukci a token podpisu do datového proudu Microsoft zprostředkujícího jazyka (MSIL).
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::SignatureHelper ^ signature);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::SignatureHelper ^ signature);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.SignatureHelper signature);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.SignatureHelper signature);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.SignatureHelper -> unit
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.SignatureHelper -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.SignatureHelper -> unit
Public MustOverride Sub Emit (opcode As OpCode, signature As SignatureHelper)
Public Overridable Sub Emit (opcode As OpCode, signature As SignatureHelper)
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 instrukcí jsou definovány ve výčtu OpCodes .
Platí pro
Emit(OpCode, Label[])
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
Umístí zadanou instrukci do datového proudu Microsoft zprostředkujícího jazyka (MSIL) a po dokončení oprav ponechá místo na zahrnutí popisku.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, cli::array <System::Reflection::Emit::Label> ^ labels);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, cli::array <System::Reflection::Emit::Label> ^ labels);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label[] labels);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label[] labels);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label[] -> unit
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label[] -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label[] -> unit
Public MustOverride Sub Emit (opcode As OpCode, labels As Label())
Public Overridable Sub Emit (opcode As OpCode, labels As Label())
Parametry
- opcode
- OpCode
Instrukce MSIL, která se má vysílat do datového proudu.
- labels
- Label[]
Pole objektů popisků, do kterých se má větvet z tohoto umístění. Použijí se všechny popisky.
Příklady
Následující ukázka kódu znázorňuje vytvoření dynamické metody pomocí tabulky jump. Jump table je sestaven pomocí pole .Label
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
class DynamicJumpTableDemo
{
public static Type BuildMyType()
{
AppDomain myDomain = Thread.GetDomain();
AssemblyName myAsmName = new AssemblyName();
myAsmName.Name = "MyDynamicAssembly";
AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
myAsmName,
AssemblyBuilderAccess.Run);
ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(
"MyJumpTableDemo");
TypeBuilder myTypeBuilder = myModBuilder.DefineType("JumpTableDemo",
TypeAttributes.Public);
MethodBuilder myMthdBuilder = myTypeBuilder.DefineMethod("SwitchMe",
MethodAttributes.Public |
MethodAttributes.Static,
typeof(string),
new Type[] {typeof(int)});
ILGenerator myIL = myMthdBuilder.GetILGenerator();
Label defaultCase = myIL.DefineLabel();
Label endOfMethod = myIL.DefineLabel();
// We are initializing our jump table. Note that the labels
// will be placed later using the MarkLabel method.
Label[] jumpTable = new Label[] { myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel() };
// arg0, the number we passed, is pushed onto the stack.
// In this case, due to the design of the code sample,
// the value pushed onto the stack happens to match the
// index of the label (in IL terms, the index of the offset
// in the jump table). If this is not the case, such as
// when switching based on non-integer values, rules for the correspondence
// between the possible case values and each index of the offsets
// must be established outside of the ILGenerator.Emit calls,
// much as a compiler would.
myIL.Emit(OpCodes.Ldarg_0);
myIL.Emit(OpCodes.Switch, jumpTable);
// Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase);
// Case arg0 = 0
myIL.MarkLabel(jumpTable[0]);
myIL.Emit(OpCodes.Ldstr, "are no bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 1
myIL.MarkLabel(jumpTable[1]);
myIL.Emit(OpCodes.Ldstr, "is one banana");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 2
myIL.MarkLabel(jumpTable[2]);
myIL.Emit(OpCodes.Ldstr, "are two bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 3
myIL.MarkLabel(jumpTable[3]);
myIL.Emit(OpCodes.Ldstr, "are three bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 4
myIL.MarkLabel(jumpTable[4]);
myIL.Emit(OpCodes.Ldstr, "are four bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Default case
myIL.MarkLabel(defaultCase);
myIL.Emit(OpCodes.Ldstr, "are many bananas");
myIL.MarkLabel(endOfMethod);
myIL.Emit(OpCodes.Ret);
return myTypeBuilder.CreateType();
}
public static void Main()
{
Type myType = BuildMyType();
Console.Write("Enter an integer between 0 and 5: ");
int theValue = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("---");
Object myInstance = Activator.CreateInstance(myType, new object[0]);
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe",
BindingFlags.InvokeMethod,
null,
myInstance,
new object[] {theValue}));
}
}
Imports System.Threading
Imports System.Reflection
Imports System.Reflection.Emit
_
Class DynamicJumpTableDemo
Public Shared Function BuildMyType() As Type
Dim myDomain As AppDomain = Thread.GetDomain()
Dim myAsmName As New AssemblyName()
myAsmName.Name = "MyDynamicAssembly"
Dim myAsmBuilder As AssemblyBuilder = myDomain.DefineDynamicAssembly(myAsmName, _
AssemblyBuilderAccess.Run)
Dim myModBuilder As ModuleBuilder = myAsmBuilder.DefineDynamicModule("MyJumpTableDemo")
Dim myTypeBuilder As TypeBuilder = myModBuilder.DefineType("JumpTableDemo", _
TypeAttributes.Public)
Dim myMthdBuilder As MethodBuilder = myTypeBuilder.DefineMethod("SwitchMe", _
MethodAttributes.Public Or MethodAttributes.Static, _
GetType(String), New Type() {GetType(Integer)})
Dim myIL As ILGenerator = myMthdBuilder.GetILGenerator()
Dim defaultCase As Label = myIL.DefineLabel()
Dim endOfMethod As Label = myIL.DefineLabel()
' We are initializing our jump table. Note that the labels
' will be placed later using the MarkLabel method.
Dim jumpTable() As Label = {myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel()}
' arg0, the number we passed, is pushed onto the stack.
' In this case, due to the design of the code sample,
' the value pushed onto the stack happens to match the
' index of the label (in IL terms, the index of the offset
' in the jump table). If this is not the case, such as
' when switching based on non-integer values, rules for the correspondence
' between the possible case values and each index of the offsets
' must be established outside of the ILGenerator.Emit calls,
' much as a compiler would.
myIL.Emit(OpCodes.Ldarg_0)
myIL.Emit(OpCodes.Switch, jumpTable)
' Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase)
' Case arg0 = 0
myIL.MarkLabel(jumpTable(0))
myIL.Emit(OpCodes.Ldstr, "are no bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 1
myIL.MarkLabel(jumpTable(1))
myIL.Emit(OpCodes.Ldstr, "is one banana")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 2
myIL.MarkLabel(jumpTable(2))
myIL.Emit(OpCodes.Ldstr, "are two bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 3
myIL.MarkLabel(jumpTable(3))
myIL.Emit(OpCodes.Ldstr, "are three bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 4
myIL.MarkLabel(jumpTable(4))
myIL.Emit(OpCodes.Ldstr, "are four bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Default case
myIL.MarkLabel(defaultCase)
myIL.Emit(OpCodes.Ldstr, "are many bananas")
myIL.MarkLabel(endOfMethod)
myIL.Emit(OpCodes.Ret)
Return myTypeBuilder.CreateType()
End Function 'BuildMyType
Public Shared Sub Main()
Dim myType As Type = BuildMyType()
Console.Write("Enter an integer between 0 and 5: ")
Dim theValue As Integer = Convert.ToInt32(Console.ReadLine())
Console.WriteLine("---")
Dim myInstance As [Object] = Activator.CreateInstance(myType, New Object() {})
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe", _
BindingFlags.InvokeMethod, Nothing, _
myInstance, New Object() {theValue}))
End Sub
End Class
Poznámky
Vygeneruje tabulku přepínačů.
Hodnoty instrukcí jsou definovány ve výčtu OpCodes .
Popisky se vytvářejí pomocí DefineLabel a jejich umístění v rámci datového proudu je opraveno pomocí MarkLabel. Pokud se použije instrukce s jedním bajtem, popisek může představovat skok maximálně 127 bajtů podél datového proudu.
opcode musí představovat instrukci větve. Vzhledem k tomu, že větve jsou relativní instrukce, label budou během procesu oprav nahrazeny správným posunem na větev.
Platí pro
Emit(OpCode, MethodInfo)
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
Vloží zadanou instrukci do datového proudu Microsoft intermediate language (MSIL) následovaný tokenem metadat pro danou metodu.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::MethodInfo ^ meth);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::MethodInfo ^ meth);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.MethodInfo meth);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.MethodInfo meth);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.MethodInfo -> unit
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.MethodInfo -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.MethodInfo -> unit
Public MustOverride Sub Emit (opcode As OpCode, meth As MethodInfo)
Public Overridable Sub Emit (opcode As OpCode, meth As MethodInfo)
Parametry
- opcode
- OpCode
Instrukce MSIL, která se má vysílat do datového proudu.
- meth
- MethodInfo
Představuje MethodInfo metodu.
Výjimky
meth je null.
meth je obecná metoda, pro kterou IsGenericMethodDefinition je falsevlastnost .
Poznámky
Hodnoty instrukcí jsou definovány ve výčtu OpCodes .
meth Umístění je zaznamenáno tak, aby datový proud instrukce bylo možné v případě potřeby opravit při zachová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 MethodInfo.IsGenericMethodDefinition vlastnost musí být true.
Platí pro
Emit(OpCode, ConstructorInfo)
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
Vloží zadaný instrukční token a token metadat pro zadaný konstruktor do datového proudu Microsoft intermediate language (MSIL).
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::ConstructorInfo ^ con);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::ConstructorInfo ^ con);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.ConstructorInfo con);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.ConstructorInfo con);
[System.Runtime.InteropServices.ComVisible(true)]
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.ConstructorInfo con);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit
[<System.Runtime.InteropServices.ComVisible(true)>]
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit
Public MustOverride Sub Emit (opcode As OpCode, con As ConstructorInfo)
Public Overridable Sub Emit (opcode As OpCode, con As ConstructorInfo)
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.
Poznámky
Hodnoty instrukcí jsou definovány ve výčtu OpCodes .
con Umístění je zaznamenáno tak, aby datový proud instrukce bylo možné v případě potřeby opravit při zachování modulu do přenosného spustitelného souboru (PE).
Platí pro
Emit(OpCode, Int64)
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
Vloží zadaný instrukční a číselný argument do Microsoft zprostředkujícího jazyka (MSIL) instrukce.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, long arg);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, long arg);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, long arg);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, long arg);
abstract member Emit : System.Reflection.Emit.OpCode * int64 -> unit
abstract member Emit : System.Reflection.Emit.OpCode * int64 -> unit
override this.Emit : System.Reflection.Emit.OpCode * int64 -> unit
Public MustOverride Sub Emit (opcode As OpCode, arg As Long)
Public Overridable Sub Emit (opcode As OpCode, arg As Long)
Parametry
- opcode
- OpCode
Instrukce MSIL, která se má umístit do datového proudu.
- arg
- Int64
Číselný argument se nasdílí do datového proudu hned za pokynem.
Poznámky
Hodnoty instrukcí jsou definovány ve výčtu OpCodes .
Platí pro
Emit(OpCode, Int32)
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
Vloží zadaný instrukční a číselný argument do Microsoft zprostředkujícího jazyka (MSIL) instrukce.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, int arg);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, int arg);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, int arg);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, int arg);
abstract member Emit : System.Reflection.Emit.OpCode * int -> unit
abstract member Emit : System.Reflection.Emit.OpCode * int -> unit
override this.Emit : System.Reflection.Emit.OpCode * int -> unit
Public MustOverride Sub Emit (opcode As OpCode, arg As Integer)
Public Overridable Sub Emit (opcode As OpCode, arg As Integer)
Parametry
- opcode
- OpCode
Instrukce MSIL, která se má umístit do datového proudu.
- arg
- Int32
Číselný argument se nasdílí do datového proudu hned za pokynem.
Poznámky
Hodnoty instrukcí jsou definovány ve výčtu OpCodes .
Platí pro
Emit(OpCode, Int16)
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
Vloží zadaný instrukční a číselný argument do Microsoft zprostředkujícího jazyka (MSIL) instrukce.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, short arg);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, short arg);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, short arg);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, short arg);
abstract member Emit : System.Reflection.Emit.OpCode * int16 -> unit
abstract member Emit : System.Reflection.Emit.OpCode * int16 -> unit
override this.Emit : System.Reflection.Emit.OpCode * int16 -> unit
Public MustOverride Sub Emit (opcode As OpCode, arg As Short)
Public Overridable Sub Emit (opcode As OpCode, arg As Short)
Parametry
- opcode
- OpCode
Instrukce MSIL, která se má vysílat do datového proudu.
- arg
- Int16
Argument Int vložený do datového proudu bezprostředně po instrukci.
Poznámky
Hodnoty instrukcí jsou definovány ve výčtu OpCodes .
Platí pro
Emit(OpCode, Double)
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
Vloží zadaný instrukční a číselný argument do Microsoft zprostředkujícího jazyka (MSIL) instrukce.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, double arg);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, double arg);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, double arg);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, double arg);
abstract member Emit : System.Reflection.Emit.OpCode * double -> unit
abstract member Emit : System.Reflection.Emit.OpCode * double -> unit
override this.Emit : System.Reflection.Emit.OpCode * double -> unit
Public MustOverride Sub Emit (opcode As OpCode, arg As Double)
Public Overridable Sub Emit (opcode As OpCode, arg As Double)
Parametry
- opcode
- OpCode
Instrukce MSIL, která se má umístit do datového proudu. Definováno v výčtu OpCodes .
- arg
- Double
Číselný argument se nasdílí do datového proudu hned za pokynem.
Poznámky
Hodnoty instrukcí jsou definovány ve výčtu OpCodes .
Platí pro
Emit(OpCode, Byte)
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
Vloží zadaný instrukční a znakový argument do Microsoft zprostředkujícího jazyka (MSIL) instrukce.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Byte arg);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Byte arg);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, byte arg);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, byte arg);
abstract member Emit : System.Reflection.Emit.OpCode * byte -> unit
abstract member Emit : System.Reflection.Emit.OpCode * byte -> unit
override this.Emit : System.Reflection.Emit.OpCode * byte -> unit
Public MustOverride Sub Emit (opcode As OpCode, arg As Byte)
Public Overridable Sub Emit (opcode As OpCode, arg As Byte)
Parametry
- opcode
- OpCode
Instrukce MSIL, která se má umístit do datového proudu.
- arg
- Byte
Argument znaku se nasdílí do datového proudu bezprostředně po instrukci.
Poznámky
Hodnoty instrukcí jsou definovány ve výčtu OpCodes .
Platí pro
Emit(OpCode)
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
Umístí zadanou instrukci do datového proudu instrukcí.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode);
public abstract void Emit(System.Reflection.Emit.OpCode opcode);
public virtual void Emit(System.Reflection.Emit.OpCode opcode);
abstract member Emit : System.Reflection.Emit.OpCode -> unit
abstract member Emit : System.Reflection.Emit.OpCode -> unit
override this.Emit : System.Reflection.Emit.OpCode -> unit
Public MustOverride Sub Emit (opcode As OpCode)
Public Overridable Sub Emit (opcode As OpCode)
Parametry
- opcode
- OpCode
Instrukce jazyka MSIL (Microsoft Intermediate Language), která se má umístit do datového proudu.
Příklady
Následující ukázka kódu ukazuje použití Emit k vygenerování výstupu jazyka MSIL prostřednictvím instance ILGenerator.
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
class DynamicJumpTableDemo
{
public static Type BuildMyType()
{
AppDomain myDomain = Thread.GetDomain();
AssemblyName myAsmName = new AssemblyName();
myAsmName.Name = "MyDynamicAssembly";
AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
myAsmName,
AssemblyBuilderAccess.Run);
ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(
"MyJumpTableDemo");
TypeBuilder myTypeBuilder = myModBuilder.DefineType("JumpTableDemo",
TypeAttributes.Public);
MethodBuilder myMthdBuilder = myTypeBuilder.DefineMethod("SwitchMe",
MethodAttributes.Public |
MethodAttributes.Static,
typeof(string),
new Type[] {typeof(int)});
ILGenerator myIL = myMthdBuilder.GetILGenerator();
Label defaultCase = myIL.DefineLabel();
Label endOfMethod = myIL.DefineLabel();
// We are initializing our jump table. Note that the labels
// will be placed later using the MarkLabel method.
Label[] jumpTable = new Label[] { myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel() };
// arg0, the number we passed, is pushed onto the stack.
// In this case, due to the design of the code sample,
// the value pushed onto the stack happens to match the
// index of the label (in IL terms, the index of the offset
// in the jump table). If this is not the case, such as
// when switching based on non-integer values, rules for the correspondence
// between the possible case values and each index of the offsets
// must be established outside of the ILGenerator.Emit calls,
// much as a compiler would.
myIL.Emit(OpCodes.Ldarg_0);
myIL.Emit(OpCodes.Switch, jumpTable);
// Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase);
// Case arg0 = 0
myIL.MarkLabel(jumpTable[0]);
myIL.Emit(OpCodes.Ldstr, "are no bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 1
myIL.MarkLabel(jumpTable[1]);
myIL.Emit(OpCodes.Ldstr, "is one banana");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 2
myIL.MarkLabel(jumpTable[2]);
myIL.Emit(OpCodes.Ldstr, "are two bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 3
myIL.MarkLabel(jumpTable[3]);
myIL.Emit(OpCodes.Ldstr, "are three bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 4
myIL.MarkLabel(jumpTable[4]);
myIL.Emit(OpCodes.Ldstr, "are four bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Default case
myIL.MarkLabel(defaultCase);
myIL.Emit(OpCodes.Ldstr, "are many bananas");
myIL.MarkLabel(endOfMethod);
myIL.Emit(OpCodes.Ret);
return myTypeBuilder.CreateType();
}
public static void Main()
{
Type myType = BuildMyType();
Console.Write("Enter an integer between 0 and 5: ");
int theValue = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("---");
Object myInstance = Activator.CreateInstance(myType, new object[0]);
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe",
BindingFlags.InvokeMethod,
null,
myInstance,
new object[] {theValue}));
}
}
Imports System.Threading
Imports System.Reflection
Imports System.Reflection.Emit
_
Class DynamicJumpTableDemo
Public Shared Function BuildMyType() As Type
Dim myDomain As AppDomain = Thread.GetDomain()
Dim myAsmName As New AssemblyName()
myAsmName.Name = "MyDynamicAssembly"
Dim myAsmBuilder As AssemblyBuilder = myDomain.DefineDynamicAssembly(myAsmName, _
AssemblyBuilderAccess.Run)
Dim myModBuilder As ModuleBuilder = myAsmBuilder.DefineDynamicModule("MyJumpTableDemo")
Dim myTypeBuilder As TypeBuilder = myModBuilder.DefineType("JumpTableDemo", _
TypeAttributes.Public)
Dim myMthdBuilder As MethodBuilder = myTypeBuilder.DefineMethod("SwitchMe", _
MethodAttributes.Public Or MethodAttributes.Static, _
GetType(String), New Type() {GetType(Integer)})
Dim myIL As ILGenerator = myMthdBuilder.GetILGenerator()
Dim defaultCase As Label = myIL.DefineLabel()
Dim endOfMethod As Label = myIL.DefineLabel()
' We are initializing our jump table. Note that the labels
' will be placed later using the MarkLabel method.
Dim jumpTable() As Label = {myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel()}
' arg0, the number we passed, is pushed onto the stack.
' In this case, due to the design of the code sample,
' the value pushed onto the stack happens to match the
' index of the label (in IL terms, the index of the offset
' in the jump table). If this is not the case, such as
' when switching based on non-integer values, rules for the correspondence
' between the possible case values and each index of the offsets
' must be established outside of the ILGenerator.Emit calls,
' much as a compiler would.
myIL.Emit(OpCodes.Ldarg_0)
myIL.Emit(OpCodes.Switch, jumpTable)
' Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase)
' Case arg0 = 0
myIL.MarkLabel(jumpTable(0))
myIL.Emit(OpCodes.Ldstr, "are no bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 1
myIL.MarkLabel(jumpTable(1))
myIL.Emit(OpCodes.Ldstr, "is one banana")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 2
myIL.MarkLabel(jumpTable(2))
myIL.Emit(OpCodes.Ldstr, "are two bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 3
myIL.MarkLabel(jumpTable(3))
myIL.Emit(OpCodes.Ldstr, "are three bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 4
myIL.MarkLabel(jumpTable(4))
myIL.Emit(OpCodes.Ldstr, "are four bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Default case
myIL.MarkLabel(defaultCase)
myIL.Emit(OpCodes.Ldstr, "are many bananas")
myIL.MarkLabel(endOfMethod)
myIL.Emit(OpCodes.Ret)
Return myTypeBuilder.CreateType()
End Function 'BuildMyType
Public Shared Sub Main()
Dim myType As Type = BuildMyType()
Console.Write("Enter an integer between 0 and 5: ")
Dim theValue As Integer = Convert.ToInt32(Console.ReadLine())
Console.WriteLine("---")
Dim myInstance As [Object] = Activator.CreateInstance(myType, New Object() {})
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe", _
BindingFlags.InvokeMethod, Nothing, _
myInstance, New Object() {theValue}))
End Sub
End Class
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í poskytuje operand se 4 bajty, modul runtime vygeneruje do instrukčního datového proudu dva další bajty. Tyto nadbytečné bajty budou Nop pokyny.
Hodnoty instrukcí jsou definovány v OpCodes.
Platí pro
Emit(OpCode, Label)
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
- Zdroj:
- ILGenerator.cs
Umístí zadanou instrukci do datového proudu Microsoft zprostředkujícího jazyka (MSIL) a po dokončení oprav ponechá místo na zahrnutí popisku.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::Label label);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::Label label);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label label);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label label);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label -> unit
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label -> unit
Public MustOverride Sub Emit (opcode As OpCode, label As Label)
Public Overridable Sub Emit (opcode As OpCode, label As Label)
Parametry
- opcode
- OpCode
Instrukce MSIL, která se má vysílat do datového proudu.
- label
- Label
Popisek, do kterého chcete větev z tohoto umístění.
Příklady
Následující ukázka kódu znázorňuje vytvoření dynamické metody pomocí tabulky jump. Jump table je sestaven pomocí pole .Label
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
class DynamicJumpTableDemo
{
public static Type BuildMyType()
{
AppDomain myDomain = Thread.GetDomain();
AssemblyName myAsmName = new AssemblyName();
myAsmName.Name = "MyDynamicAssembly";
AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
myAsmName,
AssemblyBuilderAccess.Run);
ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(
"MyJumpTableDemo");
TypeBuilder myTypeBuilder = myModBuilder.DefineType("JumpTableDemo",
TypeAttributes.Public);
MethodBuilder myMthdBuilder = myTypeBuilder.DefineMethod("SwitchMe",
MethodAttributes.Public |
MethodAttributes.Static,
typeof(string),
new Type[] {typeof(int)});
ILGenerator myIL = myMthdBuilder.GetILGenerator();
Label defaultCase = myIL.DefineLabel();
Label endOfMethod = myIL.DefineLabel();
// We are initializing our jump table. Note that the labels
// will be placed later using the MarkLabel method.
Label[] jumpTable = new Label[] { myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel() };
// arg0, the number we passed, is pushed onto the stack.
// In this case, due to the design of the code sample,
// the value pushed onto the stack happens to match the
// index of the label (in IL terms, the index of the offset
// in the jump table). If this is not the case, such as
// when switching based on non-integer values, rules for the correspondence
// between the possible case values and each index of the offsets
// must be established outside of the ILGenerator.Emit calls,
// much as a compiler would.
myIL.Emit(OpCodes.Ldarg_0);
myIL.Emit(OpCodes.Switch, jumpTable);
// Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase);
// Case arg0 = 0
myIL.MarkLabel(jumpTable[0]);
myIL.Emit(OpCodes.Ldstr, "are no bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 1
myIL.MarkLabel(jumpTable[1]);
myIL.Emit(OpCodes.Ldstr, "is one banana");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 2
myIL.MarkLabel(jumpTable[2]);
myIL.Emit(OpCodes.Ldstr, "are two bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 3
myIL.MarkLabel(jumpTable[3]);
myIL.Emit(OpCodes.Ldstr, "are three bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 4
myIL.MarkLabel(jumpTable[4]);
myIL.Emit(OpCodes.Ldstr, "are four bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Default case
myIL.MarkLabel(defaultCase);
myIL.Emit(OpCodes.Ldstr, "are many bananas");
myIL.MarkLabel(endOfMethod);
myIL.Emit(OpCodes.Ret);
return myTypeBuilder.CreateType();
}
public static void Main()
{
Type myType = BuildMyType();
Console.Write("Enter an integer between 0 and 5: ");
int theValue = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("---");
Object myInstance = Activator.CreateInstance(myType, new object[0]);
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe",
BindingFlags.InvokeMethod,
null,
myInstance,
new object[] {theValue}));
}
}
Imports System.Threading
Imports System.Reflection
Imports System.Reflection.Emit
_
Class DynamicJumpTableDemo
Public Shared Function BuildMyType() As Type
Dim myDomain As AppDomain = Thread.GetDomain()
Dim myAsmName As New AssemblyName()
myAsmName.Name = "MyDynamicAssembly"
Dim myAsmBuilder As AssemblyBuilder = myDomain.DefineDynamicAssembly(myAsmName, _
AssemblyBuilderAccess.Run)
Dim myModBuilder As ModuleBuilder = myAsmBuilder.DefineDynamicModule("MyJumpTableDemo")
Dim myTypeBuilder As TypeBuilder = myModBuilder.DefineType("JumpTableDemo", _
TypeAttributes.Public)
Dim myMthdBuilder As MethodBuilder = myTypeBuilder.DefineMethod("SwitchMe", _
MethodAttributes.Public Or MethodAttributes.Static, _
GetType(String), New Type() {GetType(Integer)})
Dim myIL As ILGenerator = myMthdBuilder.GetILGenerator()
Dim defaultCase As Label = myIL.DefineLabel()
Dim endOfMethod As Label = myIL.DefineLabel()
' We are initializing our jump table. Note that the labels
' will be placed later using the MarkLabel method.
Dim jumpTable() As Label = {myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel()}
' arg0, the number we passed, is pushed onto the stack.
' In this case, due to the design of the code sample,
' the value pushed onto the stack happens to match the
' index of the label (in IL terms, the index of the offset
' in the jump table). If this is not the case, such as
' when switching based on non-integer values, rules for the correspondence
' between the possible case values and each index of the offsets
' must be established outside of the ILGenerator.Emit calls,
' much as a compiler would.
myIL.Emit(OpCodes.Ldarg_0)
myIL.Emit(OpCodes.Switch, jumpTable)
' Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase)
' Case arg0 = 0
myIL.MarkLabel(jumpTable(0))
myIL.Emit(OpCodes.Ldstr, "are no bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 1
myIL.MarkLabel(jumpTable(1))
myIL.Emit(OpCodes.Ldstr, "is one banana")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 2
myIL.MarkLabel(jumpTable(2))
myIL.Emit(OpCodes.Ldstr, "are two bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 3
myIL.MarkLabel(jumpTable(3))
myIL.Emit(OpCodes.Ldstr, "are three bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 4
myIL.MarkLabel(jumpTable(4))
myIL.Emit(OpCodes.Ldstr, "are four bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Default case
myIL.MarkLabel(defaultCase)
myIL.Emit(OpCodes.Ldstr, "are many bananas")
myIL.MarkLabel(endOfMethod)
myIL.Emit(OpCodes.Ret)
Return myTypeBuilder.CreateType()
End Function 'BuildMyType
Public Shared Sub Main()
Dim myType As Type = BuildMyType()
Console.Write("Enter an integer between 0 and 5: ")
Dim theValue As Integer = Convert.ToInt32(Console.ReadLine())
Console.WriteLine("---")
Dim myInstance As [Object] = Activator.CreateInstance(myType, New Object() {})
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe", _
BindingFlags.InvokeMethod, Nothing, _
myInstance, New Object() {theValue}))
End Sub
End Class
Poznámky
Hodnoty instrukcí jsou definovány ve výčtu OpCodes .
Popisky se vytvářejí pomocí DefineLabela jejich umístění v rámci datového proudu je opraveno pomocí MarkLabel. Pokud se použije instrukce s jedním bajtem, popisek může představovat skok maximálně 127 bajtů podél datového proudu.
opcode musí představovat instrukci větve. Vzhledem k tomu, že větve jsou relativní instrukce, label budou během procesu oprav nahrazeny správným posunem na větev.