ILGenerator.Emit Méthode
Définition
Important
Certaines informations portent sur la préversion du produit qui est susceptible d’être en grande partie modifiée avant sa publication. Microsoft exclut toute garantie, expresse ou implicite, concernant les informations fournies ici.
Place une instruction sur le flux MSIL (Microsoft Intermediate Language) du compilateur juste-à-temps (JIT).
Surcharges
| Nom | Description |
|---|---|
| Emit(OpCode, LocalBuilder) |
Place l’instruction spécifiée dans le flux msIL (Microsoft intermediate language) suivi de l’index de la variable locale donnée. |
| Emit(OpCode, Type) |
Place l’instruction spécifiée sur le flux msIL (Microsoft intermediate language) suivi du jeton de métadonnées pour le type donné. |
| Emit(OpCode, String) |
Place l’instruction spécifiée sur le flux msIL (Microsoft intermediate language) suivi du jeton de métadonnées pour la chaîne donnée. |
| Emit(OpCode, Single) |
Place l’instruction et l’argument numérique spécifiés dans le flux de Microsoft langage intermédiaire (MSIL) d’instructions. |
| Emit(OpCode, SByte) |
Place l’instruction et l’argument de caractère spécifiés dans le flux d’instructions msIL (Microsoft intermediate language). |
| Emit(OpCode, FieldInfo) |
Place l’instruction et le jeton de métadonnées spécifiés pour le champ spécifié dans le flux de Microsoft langage intermédiaire (MSIL) d’instructions. |
| Emit(OpCode, SignatureHelper) |
Place l’instruction spécifiée et un jeton de signature dans le flux d’instructions msIL (Microsoft intermediate language). |
| Emit(OpCode, Label[]) |
Place l’instruction spécifiée dans le flux msIL (Microsoft intermediate language) et laisse de l’espace pour inclure une étiquette lorsque des correctifs sont effectués. |
| Emit(OpCode, MethodInfo) |
Place l’instruction spécifiée sur le flux msIL (Microsoft intermediate language) suivi du jeton de métadonnées pour la méthode donnée. |
| Emit(OpCode, ConstructorInfo) |
Place l’instruction et le jeton de métadonnées spécifiés pour le constructeur spécifié dans le flux de Microsoft langage intermédiaire (MSIL) d’instructions. |
| Emit(OpCode, Int64) |
Place l’instruction et l’argument numérique spécifiés dans le flux de Microsoft langage intermédiaire (MSIL) d’instructions. |
| Emit(OpCode, Int32) |
Place l’instruction et l’argument numérique spécifiés dans le flux de Microsoft langage intermédiaire (MSIL) d’instructions. |
| Emit(OpCode, Int16) |
Place l’instruction et l’argument numérique spécifiés dans le flux de Microsoft langage intermédiaire (MSIL) d’instructions. |
| Emit(OpCode, Double) |
Place l’instruction et l’argument numérique spécifiés dans le flux de Microsoft langage intermédiaire (MSIL) d’instructions. |
| Emit(OpCode, Byte) |
Place l’instruction et l’argument de caractère spécifiés dans le flux d’instructions msIL (Microsoft intermediate language). |
| Emit(OpCode) |
Place l’instruction spécifiée dans le flux d’instructions. |
| Emit(OpCode, Label) |
Place l’instruction spécifiée dans le flux msIL (Microsoft intermediate language) et laisse de l’espace pour inclure une étiquette lorsque des correctifs sont effectués. |
Emit(OpCode, LocalBuilder)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Place l’instruction spécifiée dans le flux msIL (Microsoft intermediate language) suivi de l’index de la variable locale donnée.
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)
Paramètres
- opcode
- OpCode
Instruction MSIL à émettre sur le flux.
- local
- LocalBuilder
Variable locale.
Exceptions
La méthode parente du local paramètre ne correspond pas à la méthode associée à ce ILGeneratorparamètre .
local a la valeur null.
opcode est une instruction sur un octet et local représente une variable locale avec un index supérieur Byte.MaxValueà .
Remarques
Les valeurs d’instruction sont définies dans l’énumération OpCodes .
S’applique à
Emit(OpCode, Type)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Place l’instruction spécifiée sur le flux msIL (Microsoft intermediate language) suivi du jeton de métadonnées pour le type donné.
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)
Paramètres
- opcode
- OpCode
Instruction MSIL à placer dans le flux.
- cls
- Type
Un Type.
Exceptions
cls a la valeur null.
Remarques
Les valeurs d’instruction sont définies dans l’énumération OpCodes . L’emplacement d’enregistrement cls est enregistré afin que le jeton puisse être corrigé si nécessaire lors de la persistance du module dans un fichier exécutable portable (PE).
S’applique à
Emit(OpCode, String)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Place l’instruction spécifiée sur le flux msIL (Microsoft intermediate language) suivi du jeton de métadonnées pour la chaîne donnée.
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)
Paramètres
- opcode
- OpCode
Instruction MSIL à émettre sur le flux.
- str
- String
String À émettre.
Remarques
Les valeurs d’instruction sont définies dans l’énumération OpCodes . L’emplacement des str correctifs futurs est enregistré si le module est conservé dans un fichier exécutable portable (PE).
S’applique à
Emit(OpCode, Single)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Place l’instruction et l’argument numérique spécifiés dans le flux de Microsoft langage intermédiaire (MSIL) d’instructions.
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)
Paramètres
- opcode
- OpCode
Instruction MSIL à placer dans le flux.
Remarques
Les valeurs d’instruction sont définies dans l’énumération OpCodes .
S’applique à
Emit(OpCode, SByte)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Important
Cette API n’est pas conforme CLS.
Place l’instruction et l’argument de caractère spécifiés dans le flux d’instructions 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)
Paramètres
- opcode
- OpCode
Instruction MSIL à placer dans le flux.
- arg
- SByte
Argument de caractère envoyé sur le flux immédiatement après l’instruction.
- Attributs
Remarques
Les valeurs d’instruction sont définies dans l’énumération OpCodes .
S’applique à
Emit(OpCode, FieldInfo)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Place l’instruction et le jeton de métadonnées spécifiés pour le champ spécifié dans le flux de Microsoft langage intermédiaire (MSIL) d’instructions.
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)
Paramètres
- opcode
- OpCode
Instruction MSIL à émettre sur le flux.
- field
- FieldInfo
Représentant FieldInfo un champ.
Remarques
Les valeurs d’instruction sont définies dans l’énumération OpCodes . L’emplacement d’enregistrement field est enregistré afin que le flux d’instructions puisse être corrigé si nécessaire lors de la persistance du module dans un fichier exécutable portable (PE).
S’applique à
Emit(OpCode, SignatureHelper)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Place l’instruction spécifiée et un jeton de signature dans le flux d’instructions msIL (Microsoft intermediate language).
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)
Paramètres
- opcode
- OpCode
Instruction MSIL à émettre sur le flux.
- signature
- SignatureHelper
Assistance pour la construction d’un jeton de signature.
Exceptions
signature a la valeur null.
Remarques
Les valeurs d’instruction sont définies dans l’énumération OpCodes .
S’applique à
Emit(OpCode, Label[])
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Place l’instruction spécifiée dans le flux msIL (Microsoft intermediate language) et laisse de l’espace pour inclure une étiquette lorsque des correctifs sont effectués.
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())
Paramètres
- opcode
- OpCode
Instruction MSIL à émettre sur le flux.
- labels
- Label[]
Tableau d’objets d’étiquette auxquels se brancher à partir de cet emplacement. Toutes les étiquettes seront utilisées.
Exemples
L’exemple de code ci-dessous illustre la création d’une méthode dynamique avec une table de raccourcis. La table de raccourcis est générée à l’aide d’un tableau de 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
Remarques
Émet une table de commutateurs.
Les valeurs d’instruction sont définies dans l’énumération OpCodes .
Les étiquettes sont créées à l’aide DefineLabel et leur emplacement dans le flux est fixe à l’aide MarkLabelde . Si une instruction sur un octet est utilisée, l’étiquette peut représenter un saut d’au plus 127 octets le long du flux.
opcode doit représenter une instruction de branche. Étant donné que les branches sont des instructions relatives, label elles sont remplacées par le décalage correct vers la branche pendant le processus de correction.
S’applique à
Emit(OpCode, MethodInfo)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Place l’instruction spécifiée sur le flux msIL (Microsoft intermediate language) suivi du jeton de métadonnées pour la méthode donnée.
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)
Paramètres
- opcode
- OpCode
Instruction MSIL à émettre sur le flux.
- meth
- MethodInfo
Représentant MethodInfo une méthode.
Exceptions
meth a la valeur null.
meth est une méthode générique pour laquelle la IsGenericMethodDefinition propriété est false.
Remarques
Les valeurs d’instruction sont définies dans l’énumération OpCodes .
L’emplacement d’enregistrement meth est enregistré afin que le flux d’instructions puisse être corrigé si nécessaire lors de la persistance du module dans un fichier exécutable portable (PE).
Si meth elle représente une méthode générique, elle doit être une définition de méthode générique. Autrement dit, sa propriété MethodInfo.IsGenericMethodDefinition doit être true.
S’applique à
Emit(OpCode, ConstructorInfo)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Place l’instruction et le jeton de métadonnées spécifiés pour le constructeur spécifié dans le flux de Microsoft langage intermédiaire (MSIL) d’instructions.
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)
Paramètres
- opcode
- OpCode
Instruction MSIL à émettre sur le flux.
- con
- ConstructorInfo
Représentant ConstructorInfo un constructeur.
- Attributs
Exceptions
con a la valeur null.
Remarques
Les valeurs d’instruction sont définies dans l’énumération OpCodes .
L’emplacement d’enregistrement con est enregistré afin que le flux d’instructions puisse être corrigé si nécessaire lors de la persistance du module dans un fichier exécutable portable (PE).
S’applique à
Emit(OpCode, Int64)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Place l’instruction et l’argument numérique spécifiés dans le flux de Microsoft langage intermédiaire (MSIL) d’instructions.
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)
Paramètres
- opcode
- OpCode
Instruction MSIL à placer dans le flux.
- arg
- Int64
Argument numérique envoyé sur le flux immédiatement après l’instruction.
Remarques
Les valeurs d’instruction sont définies dans l’énumération OpCodes .
S’applique à
Emit(OpCode, Int32)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Place l’instruction et l’argument numérique spécifiés dans le flux de Microsoft langage intermédiaire (MSIL) d’instructions.
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)
Paramètres
- opcode
- OpCode
Instruction MSIL à placer dans le flux.
- arg
- Int32
Argument numérique envoyé sur le flux immédiatement après l’instruction.
Remarques
Les valeurs d’instruction sont définies dans l’énumération OpCodes .
S’applique à
Emit(OpCode, Int16)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Place l’instruction et l’argument numérique spécifiés dans le flux de Microsoft langage intermédiaire (MSIL) d’instructions.
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)
Paramètres
- opcode
- OpCode
Instruction MSIL à émettre sur le flux.
- arg
- Int16
L’argument Int a envoyé (push) sur le flux immédiatement après l’instruction.
Remarques
Les valeurs d’instruction sont définies dans l’énumération OpCodes .
S’applique à
Emit(OpCode, Double)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Place l’instruction et l’argument numérique spécifiés dans le flux de Microsoft langage intermédiaire (MSIL) d’instructions.
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)
Paramètres
- opcode
- OpCode
Instruction MSIL à placer dans le flux. Défini dans l’énumération OpCodes .
- arg
- Double
Argument numérique envoyé sur le flux immédiatement après l’instruction.
Remarques
Les valeurs d’instruction sont définies dans l’énumération OpCodes .
S’applique à
Emit(OpCode, Byte)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Place l’instruction et l’argument de caractère spécifiés dans le flux d’instructions msIL (Microsoft intermediate language).
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)
Paramètres
- opcode
- OpCode
Instruction MSIL à placer dans le flux.
- arg
- Byte
Argument de caractère envoyé sur le flux immédiatement après l’instruction.
Remarques
Les valeurs d’instruction sont définies dans l’énumération OpCodes .
S’applique à
Emit(OpCode)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Place l’instruction spécifiée dans le flux d’instructions.
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)
Paramètres
- opcode
- OpCode
Instruction MSIL (Microsoft Intermediate Language) à placer dans le flux.
Exemples
L’exemple de code ci-dessous illustre l’utilisation de la génération de Emit sortie MSIL via une instance de 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
Remarques
Si le opcode paramètre requiert un argument, l’appelant doit s’assurer que la longueur de l’argument correspond à la longueur du paramètre déclaré. Sinon, les résultats seront imprévisibles. Par exemple, si l’instruction Emit nécessite un opérande de 2 octets et que l’appelant fournit un opérande de 4 octets, le runtime émet deux octets supplémentaires dans le flux d’instructions. Ces octets supplémentaires seront Nop des instructions.
Les valeurs d’instruction sont définies dans OpCodes.
S’applique à
Emit(OpCode, Label)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Place l’instruction spécifiée dans le flux msIL (Microsoft intermediate language) et laisse de l’espace pour inclure une étiquette lorsque des correctifs sont effectués.
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)
Paramètres
- opcode
- OpCode
Instruction MSIL à émettre sur le flux.
- label
- Label
Étiquette à laquelle faire la branche à partir de cet emplacement.
Exemples
L’exemple de code ci-dessous illustre la création d’une méthode dynamique avec une table de raccourcis. La table de raccourcis est générée à l’aide d’un tableau de 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
Remarques
Les valeurs d’instruction sont définies dans l’énumération OpCodes .
Les étiquettes sont créées à l’aide DefineLabeldu flux, et leur emplacement dans le flux est résolu à l’aide MarkLabelde . Si une instruction sur un octet est utilisée, l’étiquette peut représenter un saut d’au plus 127 octets le long du flux.
opcode doit représenter une instruction de branche. Étant donné que les branches sont des instructions relatives, label elles sont remplacées par le décalage correct vers la branche pendant le processus de correction.