ILGenerator.Emit Methode
Definition
Wichtig
Einige Informationen beziehen sich auf Vorabversionen, die vor dem Release ggf. grundlegend überarbeitet werden. Microsoft übernimmt hinsichtlich der hier bereitgestellten Informationen keine Gewährleistungen, seien sie ausdrücklich oder konkludent.
Fügt eine Anweisung in den Microsoft MSIL-Datenstrom (Intermediate Language) für den Just-in-Time-Compiler (JIT) ein.
Überlädt
| Name | Beschreibung |
|---|---|
| Emit(OpCode, LocalBuilder) |
Fügt die angegebene Anweisung in den Microsoft MSIL-Datenstrom (Intermediate Language) ein, gefolgt vom Index der angegebenen lokalen Variablen. |
| Emit(OpCode, Type) |
Fügt die angegebene Anweisung in den Microsoft MSIL-Datenstrom (Intermediate Language) ein, gefolgt vom Metadatentoken für den angegebenen Typ. |
| Emit(OpCode, String) |
Fügt die angegebene Anweisung in den Microsoft MSIL-Datenstrom (Intermediate Language) ein, gefolgt vom Metadatentoken für die angegebene Zeichenfolge. |
| Emit(OpCode, Single) |
Fügt die angegebene Anweisung und das numerische Argument in den Microsoft MSIL-Datenstrom (Intermediate Language) der Anweisungen ein. |
| Emit(OpCode, SByte) |
Fügt das angegebene Anweisungs- und Zeichenargument in den Microsoft MSIL-Datenstrom (Intermediate Language) der Anweisungen ein. |
| Emit(OpCode, FieldInfo) |
Fügt das angegebene Anweisungs- und Metadatentoken für das angegebene Feld in den Microsoft MSIL-Datenstrom (Intermediate Language) der Anweisungen ein. |
| Emit(OpCode, SignatureHelper) |
Fügt die angegebene Anweisung und ein Signaturtoken in den Microsoft MSIL-Datenstrom (Intermediate Language) von Anweisungen ein. |
| Emit(OpCode, Label[]) |
Fügt die angegebene Anweisung in den Microsoft MSIL-Datenstrom (Intermediate Language) ein und lässt Platz, um eine Beschriftung einzuschließen, wenn Korrekturen durchgeführt werden. |
| Emit(OpCode, MethodInfo) |
Fügt die angegebene Anweisung in den Microsoft MSIL-Datenstrom (Intermediate Language) ein, gefolgt vom Metadatentoken für die angegebene Methode. |
| Emit(OpCode, ConstructorInfo) |
Fügt das angegebene Anweisungs- und Metadatentoken für den angegebenen Konstruktor in den Microsoft MSIL-Datenstrom (Intermediate Language) der Anweisungen ein. |
| Emit(OpCode, Int64) |
Fügt die angegebene Anweisung und das numerische Argument in den Microsoft MSIL-Datenstrom (Intermediate Language) der Anweisungen ein. |
| Emit(OpCode, Int32) |
Fügt die angegebene Anweisung und das numerische Argument in den Microsoft MSIL-Datenstrom (Intermediate Language) der Anweisungen ein. |
| Emit(OpCode, Int16) |
Fügt die angegebene Anweisung und das numerische Argument in den Microsoft MSIL-Datenstrom (Intermediate Language) der Anweisungen ein. |
| Emit(OpCode, Double) |
Fügt die angegebene Anweisung und das numerische Argument in den Microsoft MSIL-Datenstrom (Intermediate Language) der Anweisungen ein. |
| Emit(OpCode, Byte) |
Fügt das angegebene Anweisungs- und Zeichenargument in den Microsoft MSIL-Datenstrom (Intermediate Language) der Anweisungen ein. |
| Emit(OpCode) |
Platziert die angegebene Anweisung in den Datenstrom der Anweisungen. |
| Emit(OpCode, Label) |
Fügt die angegebene Anweisung in den Microsoft MSIL-Datenstrom (Intermediate Language) ein und lässt Platz, um eine Beschriftung einzuschließen, wenn Korrekturen durchgeführt werden. |
Emit(OpCode, LocalBuilder)
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
Fügt die angegebene Anweisung in den Microsoft MSIL-Datenstrom (Intermediate Language) ein, gefolgt vom Index der angegebenen lokalen Variablen.
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)
Parameter
- opcode
- OpCode
Die MSIL-Anweisung, die im Datenstrom ausgegeben werden soll.
- local
- LocalBuilder
Eine lokale Variable.
Ausnahmen
Die übergeordnete Methode des local Parameters stimmt nicht mit der methode überein, die diesem ILGeneratorzugeordnet ist.
local ist null.
opcode ist eine Einzelbyte-Anweisung und local stellt eine lokale Variable mit einem Index dar, der größer als ist Byte.MaxValue.
Hinweise
Die Anweisungswerte werden in der OpCodes Enumeration definiert.
Gilt für:
Emit(OpCode, Type)
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
Fügt die angegebene Anweisung in den Microsoft MSIL-Datenstrom (Intermediate Language) ein, gefolgt vom Metadatentoken für den angegebenen 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)
Parameter
- opcode
- OpCode
Die MSIL-Anweisung, die auf den Strom gesetzt werden soll.
- cls
- Type
Ein Type.
Ausnahmen
cls ist null.
Hinweise
Die Anweisungswerte werden in der OpCodes Enumeration definiert. Der Speicherort wird cls aufgezeichnet, damit das Token bei Bedarf gepatcht werden kann, wenn das Modul in einer portablen ausführbaren Datei (PE) gespeichert wird.
Gilt für:
Emit(OpCode, String)
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
Fügt die angegebene Anweisung in den Microsoft MSIL-Datenstrom (Intermediate Language) ein, gefolgt vom Metadatentoken für die angegebene Zeichenfolge.
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)
Parameter
- opcode
- OpCode
Die MSIL-Anweisung, die im Datenstrom ausgegeben werden soll.
- str
- String
Der String ausgelassene Wert.
Hinweise
Die Anweisungswerte werden in der OpCodes Enumeration definiert. Der Speicherort wird str für zukünftige Fixups aufgezeichnet, wenn das Modul in einer portablen ausführbaren Datei (PE) gespeichert ist.
Gilt für:
Emit(OpCode, Single)
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
Fügt die angegebene Anweisung und das numerische Argument in den Microsoft MSIL-Datenstrom (Intermediate Language) der Anweisungen ein.
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)
Parameter
- opcode
- OpCode
Die MSIL-Anweisung, die auf den Strom gesetzt werden soll.
Hinweise
Die Anweisungswerte werden in der OpCodes Enumeration definiert.
Gilt für:
Emit(OpCode, SByte)
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
Wichtig
Diese API ist nicht CLS-kompatibel.
Fügt das angegebene Anweisungs- und Zeichenargument in den Microsoft MSIL-Datenstrom (Intermediate Language) der Anweisungen ein.
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)
Parameter
- opcode
- OpCode
Die MSIL-Anweisung, die auf den Strom gesetzt werden soll.
- arg
- SByte
Das Zeichenargument wurde unmittelbar nach der Anweisung auf den Datenstrom verschoben.
- Attribute
Hinweise
Die Anweisungswerte werden in der OpCodes Enumeration definiert.
Gilt für:
Emit(OpCode, FieldInfo)
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
Fügt das angegebene Anweisungs- und Metadatentoken für das angegebene Feld in den Microsoft MSIL-Datenstrom (Intermediate Language) der Anweisungen ein.
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)
Parameter
- opcode
- OpCode
Die MSIL-Anweisung, die im Datenstrom ausgegeben werden soll.
- field
- FieldInfo
A FieldInfo representing a field.
Hinweise
Die Anweisungswerte werden in der OpCodes Enumeration definiert. Der Speicherort wird field aufgezeichnet, sodass der Anweisungsdatenstrom bei Bedarf gepatcht werden kann, wenn das Modul in einer portablen ausführbaren Datei (PE) gespeichert wird.
Gilt für:
Emit(OpCode, SignatureHelper)
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
Fügt die angegebene Anweisung und ein Signaturtoken in den Microsoft MSIL-Datenstrom (Intermediate Language) von Anweisungen ein.
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)
Parameter
- opcode
- OpCode
Die MSIL-Anweisung, die im Datenstrom ausgegeben werden soll.
- signature
- SignatureHelper
Ein Hilfsprogramm zum Erstellen eines Signaturtokens.
Ausnahmen
signature ist null.
Hinweise
Die Anweisungswerte werden in der OpCodes Enumeration definiert.
Gilt für:
Emit(OpCode, Label[])
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
Fügt die angegebene Anweisung in den Microsoft MSIL-Datenstrom (Intermediate Language) ein und lässt Platz, um eine Beschriftung einzuschließen, wenn Korrekturen durchgeführt werden.
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())
Parameter
- opcode
- OpCode
Die MSIL-Anweisung, die im Datenstrom ausgegeben werden soll.
- labels
- Label[]
Das Array von Bezeichnungsobjekten, auf die von dieser Position verzweigt werden soll. Alle Etiketten werden verwendet.
Beispiele
Das folgende Codebeispiel veranschaulicht die Erstellung einer dynamischen Methode mit einer Sprungtabelle. Die Sprungtabelle wird mithilfe eines Arrays von 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
Hinweise
Gibt eine Schaltertabelle aus.
Die Anweisungswerte werden in der OpCodes Enumeration definiert.
Bezeichnungen werden mithilfe DefineLabel der Verwendung erstellt, und deren Position innerhalb des Datenstroms wird mithilfe MarkLabeldes Datenstroms behoben. Wenn eine Einzelbyte-Anweisung verwendet wird, kann die Beschriftung einen Sprung von höchstens 127 Byte entlang des Datenstroms darstellen.
opcode muss eine Verzweigungsanweisung darstellen. Da Verzweigungen relative Anweisungen sind, label wird der richtige Versatz während des Fixupprozesses durch den richtigen Versatz ersetzt.
Gilt für:
Emit(OpCode, MethodInfo)
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
Fügt die angegebene Anweisung in den Microsoft MSIL-Datenstrom (Intermediate Language) ein, gefolgt vom Metadatentoken für die angegebene Methode.
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)
Parameter
- opcode
- OpCode
Die MSIL-Anweisung, die im Datenstrom ausgegeben werden soll.
- meth
- MethodInfo
A MethodInfo representing a method.
Ausnahmen
meth ist null.
meth ist eine generische Methode, für die die IsGenericMethodDefinition Eigenschaft ist false.
Hinweise
Die Anweisungswerte werden in der OpCodes Enumeration definiert.
Der Speicherort wird meth aufgezeichnet, sodass der Anweisungsdatenstrom bei Bedarf gepatcht werden kann, wenn das Modul in einer portablen ausführbaren Datei (PE) gespeichert wird.
Wenn meth eine generische Methode darstellt, muss es sich um eine generische Methodendefinition sein. Das heißt, die MethodInfo.IsGenericMethodDefinition-Eigenschaft muss sein true.
Gilt für:
Emit(OpCode, ConstructorInfo)
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
Fügt das angegebene Anweisungs- und Metadatentoken für den angegebenen Konstruktor in den Microsoft MSIL-Datenstrom (Intermediate Language) der Anweisungen ein.
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)
Parameter
- opcode
- OpCode
Die MSIL-Anweisung, die im Datenstrom ausgegeben werden soll.
- con
- ConstructorInfo
Ein ConstructorInfo Konstruktor.
- Attribute
Ausnahmen
con ist null.
Hinweise
Die Anweisungswerte werden in der OpCodes Enumeration definiert.
Der Speicherort wird con aufgezeichnet, sodass der Anweisungsdatenstrom bei Bedarf gepatcht werden kann, wenn das Modul in einer portablen ausführbaren Datei (PE) gespeichert wird.
Gilt für:
Emit(OpCode, Int64)
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
Fügt die angegebene Anweisung und das numerische Argument in den Microsoft MSIL-Datenstrom (Intermediate Language) der Anweisungen ein.
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)
Parameter
- opcode
- OpCode
Die MSIL-Anweisung, die auf den Strom gesetzt werden soll.
- arg
- Int64
Das numerische Argument wurde unmittelbar nach der Anweisung auf den Datenstrom verschoben.
Hinweise
Die Anweisungswerte werden in der OpCodes Enumeration definiert.
Gilt für:
Emit(OpCode, Int32)
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
Fügt die angegebene Anweisung und das numerische Argument in den Microsoft MSIL-Datenstrom (Intermediate Language) der Anweisungen ein.
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)
Parameter
- opcode
- OpCode
Die MSIL-Anweisung, die auf den Strom gesetzt werden soll.
- arg
- Int32
Das numerische Argument wurde unmittelbar nach der Anweisung auf den Datenstrom verschoben.
Hinweise
Die Anweisungswerte werden in der OpCodes Enumeration definiert.
Gilt für:
Emit(OpCode, Int16)
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
Fügt die angegebene Anweisung und das numerische Argument in den Microsoft MSIL-Datenstrom (Intermediate Language) der Anweisungen ein.
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)
Parameter
- opcode
- OpCode
Die MSIL-Anweisung, die im Datenstrom ausgegeben werden soll.
- arg
- Int16
Das Int Argument wurde unmittelbar nach der Anweisung auf den Datenstrom verschoben.
Hinweise
Die Anweisungswerte werden in der OpCodes Enumeration definiert.
Gilt für:
Emit(OpCode, Double)
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
Fügt die angegebene Anweisung und das numerische Argument in den Microsoft MSIL-Datenstrom (Intermediate Language) der Anweisungen ein.
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)
Parameter
- opcode
- OpCode
Die MSIL-Anweisung, die auf den Strom gesetzt werden soll. Definiert in der OpCodes Aufzählung.
- arg
- Double
Das numerische Argument wurde unmittelbar nach der Anweisung auf den Datenstrom verschoben.
Hinweise
Die Anweisungswerte werden in der OpCodes Enumeration definiert.
Gilt für:
Emit(OpCode, Byte)
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
Fügt das angegebene Anweisungs- und Zeichenargument in den Microsoft MSIL-Datenstrom (Intermediate Language) der Anweisungen ein.
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)
Parameter
- opcode
- OpCode
Die MSIL-Anweisung, die auf den Strom gesetzt werden soll.
- arg
- Byte
Das Zeichenargument wurde unmittelbar nach der Anweisung auf den Datenstrom verschoben.
Hinweise
Die Anweisungswerte werden in der OpCodes Enumeration definiert.
Gilt für:
Emit(OpCode)
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
Platziert die angegebene Anweisung in den Datenstrom der Anweisungen.
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)
Parameter
- opcode
- OpCode
Die Microsoft MSIL-Anweisung (Intermediate Language), die auf den Datenstrom gesetzt werden soll.
Beispiele
Das folgende Codebeispiel veranschaulicht die Verwendung der Emit MSIL-Ausgabe über eine Instanz von 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
Hinweise
Wenn der opcode Parameter ein Argument erfordert, muss der Aufrufer sicherstellen, dass die Argumentlänge mit der Länge des deklarierten Parameters übereinstimmt. Andernfalls sind die Ergebnisse unvorhersehbar. Wenn die Emit-Anweisung beispielsweise einen 2-Byte-Operanden erfordert und der Aufrufer einen 4-Byte-Operanden bereitstellt, gibt die Laufzeit zwei zusätzliche Bytes an den Anweisungsstream aus. Diese zusätzlichen Bytes sind Nop Anweisungen.
Die Anweisungswerte werden in OpCodesdefiniert.
Gilt für:
Emit(OpCode, Label)
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
- Quelle:
- ILGenerator.cs
Fügt die angegebene Anweisung in den Microsoft MSIL-Datenstrom (Intermediate Language) ein und lässt Platz, um eine Beschriftung einzuschließen, wenn Korrekturen durchgeführt werden.
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)
Parameter
- opcode
- OpCode
Die MSIL-Anweisung, die im Datenstrom ausgegeben werden soll.
- label
- Label
Die Bezeichnung, zu der von diesem Speicherort verzweigt werden soll.
Beispiele
Das folgende Codebeispiel veranschaulicht die Erstellung einer dynamischen Methode mit einer Sprungtabelle. Die Sprungtabelle wird mithilfe eines Arrays von 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
Hinweise
Die Anweisungswerte werden in der OpCodes Enumeration definiert.
Bezeichnungen werden mithilfe DefineLabeldes Datenstroms erstellt, und deren Position innerhalb des Datenstroms wird mithilfe von MarkLabel. festgelegt. Wenn eine Einzelbyte-Anweisung verwendet wird, kann die Beschriftung einen Sprung von höchstens 127 Byte entlang des Datenstroms darstellen.
opcode muss eine Verzweigungsanweisung darstellen. Da Verzweigungen relative Anweisungen sind, label wird der richtige Versatz während des Fixupprozesses durch den richtigen Versatz ersetzt.