ILGenerator.Emit メソッド
定義
重要
一部の情報は、リリース前に大きく変更される可能性があるプレリリースされた製品に関するものです。 Microsoft は、ここに記載されている情報について、明示または黙示を問わず、一切保証しません。
Just-In-Time (JIT) コンパイラのMicrosoft Intermediate Language (MSIL) ストリームに命令を書き込みます。
オーバーロード
| 名前 | 説明 |
|---|---|
| Emit(OpCode, LocalBuilder) |
指定した命令を、Microsoft中間言語 (MSIL) ストリームの後に、指定されたローカル変数のインデックスを配置します。 |
| Emit(OpCode, Type) |
指定した命令をMicrosoft中間言語 (MSIL) ストリームの後に、指定された型のメタデータ トークンを配置します。 |
| Emit(OpCode, String) |
指定した命令をMicrosoft中間言語 (MSIL) ストリームの後に、指定された文字列のメタデータ トークンを配置します。 |
| Emit(OpCode, Single) |
指定した命令と数値引数を、命令のMicrosoft中間言語 (MSIL) ストリームに配置します。 |
| Emit(OpCode, SByte) |
指定した命令と文字引数を、命令のMicrosoft中間言語 (MSIL) ストリームに配置します。 |
| Emit(OpCode, FieldInfo) |
指定したフィールドの指定した命令とメタデータ トークンを、命令のMicrosoft中間言語 (MSIL) ストリームに配置します。 |
| Emit(OpCode, SignatureHelper) |
指定した命令と署名トークンを、命令のMicrosoft中間言語 (MSIL) ストリームに配置します。 |
| Emit(OpCode, Label[]) |
指定した命令をMicrosoft中間言語 (MSIL) ストリームに配置し、修正が完了したときにラベルを含める領域を残します。 |
| Emit(OpCode, MethodInfo) |
指定した命令を、Microsoft中間言語 (MSIL) ストリームの後に、指定されたメソッドのメタデータ トークンを配置します。 |
| Emit(OpCode, ConstructorInfo) |
指定したコンストラクターの指定した命令とメタデータ トークンを、命令のMicrosoft中間言語 (MSIL) ストリームに配置します。 |
| Emit(OpCode, Int64) |
指定した命令と数値引数を、命令のMicrosoft中間言語 (MSIL) ストリームに配置します。 |
| Emit(OpCode, Int32) |
指定した命令と数値引数を、命令のMicrosoft中間言語 (MSIL) ストリームに配置します。 |
| Emit(OpCode, Int16) |
指定した命令と数値引数を、命令のMicrosoft中間言語 (MSIL) ストリームに配置します。 |
| Emit(OpCode, Double) |
指定した命令と数値引数を、命令のMicrosoft中間言語 (MSIL) ストリームに配置します。 |
| Emit(OpCode, Byte) |
指定した命令と文字引数を、命令のMicrosoft中間言語 (MSIL) ストリームに配置します。 |
| Emit(OpCode) |
指定した命令を命令のストリームに配置します。 |
| Emit(OpCode, Label) |
指定した命令をMicrosoft中間言語 (MSIL) ストリームに配置し、修正が完了したときにラベルを含める領域を残します。 |
Emit(OpCode, LocalBuilder)
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
指定した命令を、Microsoft中間言語 (MSIL) ストリームの後に、指定されたローカル変数のインデックスを配置します。
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)
パラメーター
- opcode
- OpCode
ストリームに出力される MSIL 命令。
- local
- LocalBuilder
ローカル変数。
例外
local パラメーターの親メソッドは、このILGeneratorに関連付けられているメソッドと一致しません。
local は nullです。
opcode は 1 バイト命令であり、 local は Byte.MaxValue より大きいインデックスを持つローカル変数を表します。
注釈
命令値は、 OpCodes 列挙型で定義されます。
適用対象
Emit(OpCode, Type)
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
指定した命令をMicrosoft中間言語 (MSIL) ストリームの後に、指定された型のメタデータ トークンを配置します。
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)
パラメーター
- opcode
- OpCode
ストリームに配置する MSIL 命令。
- cls
- Type
Type です。
例外
cls は nullです。
注釈
命令値は、 OpCodes 列挙型で定義されます。 モジュールをポータブル実行可能ファイル (PE) ファイルに永続化するときに、必要に応じてトークンに修正プログラムを適用できるように、 cls の場所が記録されます。
適用対象
Emit(OpCode, String)
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
指定した命令をMicrosoft中間言語 (MSIL) ストリームの後に、指定された文字列のメタデータ トークンを配置します。
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)
パラメーター
- opcode
- OpCode
ストリームに出力される MSIL 命令。
- str
- String
出力される String 。
注釈
命令値は、 OpCodes 列挙型で定義されます。 モジュールがポータブル実行可能ファイル (PE) ファイルに永続化されている場合、 str の場所は将来の修正のために記録されます。
適用対象
Emit(OpCode, Single)
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
指定した命令と数値引数を、命令のMicrosoft中間言語 (MSIL) ストリームに配置します。
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)
パラメーター
- opcode
- OpCode
ストリームに配置する MSIL 命令。
注釈
命令値は、 OpCodes 列挙型で定義されます。
適用対象
Emit(OpCode, SByte)
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
重要
この API は CLS 準拠ではありません。
指定した命令と文字引数を、命令のMicrosoft中間言語 (MSIL) ストリームに配置します。
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)
パラメーター
- opcode
- OpCode
ストリームに配置する MSIL 命令。
- arg
- SByte
命令の直後にストリームにプッシュされる文字引数。
- 属性
注釈
命令値は、 OpCodes 列挙型で定義されます。
適用対象
Emit(OpCode, FieldInfo)
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
指定したフィールドの指定した命令とメタデータ トークンを、命令のMicrosoft中間言語 (MSIL) ストリームに配置します。
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::FieldInfo ^ field);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::FieldInfo ^ field);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.FieldInfo field);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.FieldInfo field);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.FieldInfo -> unit
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.FieldInfo -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.FieldInfo -> unit
Public MustOverride Sub Emit (opcode As OpCode, field As FieldInfo)
Public Overridable Sub Emit (opcode As OpCode, field As FieldInfo)
パラメーター
- opcode
- OpCode
ストリームに出力される MSIL 命令。
- field
- FieldInfo
フィールドを表す FieldInfo 。
注釈
命令値は、 OpCodes 列挙型で定義されます。 モジュールをポータブル実行可能ファイル (PE) ファイルに永続化するときに、必要に応じて命令ストリームに修正プログラムを適用できるように、 field の場所が記録されます。
適用対象
Emit(OpCode, SignatureHelper)
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
指定した命令と署名トークンを、命令のMicrosoft中間言語 (MSIL) ストリームに配置します。
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::SignatureHelper ^ signature);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::SignatureHelper ^ signature);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.SignatureHelper signature);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.SignatureHelper signature);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.SignatureHelper -> unit
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.SignatureHelper -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.SignatureHelper -> unit
Public MustOverride Sub Emit (opcode As OpCode, signature As SignatureHelper)
Public Overridable Sub Emit (opcode As OpCode, signature As SignatureHelper)
パラメーター
- opcode
- OpCode
ストリームに出力される MSIL 命令。
- signature
- SignatureHelper
署名トークンを構築するためのヘルパー。
例外
signature は nullです。
注釈
命令値は、 OpCodes 列挙型で定義されます。
適用対象
Emit(OpCode, Label[])
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
指定した命令をMicrosoft中間言語 (MSIL) ストリームに配置し、修正が完了したときにラベルを含める領域を残します。
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())
パラメーター
- opcode
- OpCode
ストリームに出力される MSIL 命令。
- labels
- Label[]
この場所から分岐するラベル オブジェクトの配列。 すべてのラベルが使用されます。
例
次のコード サンプルは、ジャンプ テーブルを使用した動的メソッドの作成を示しています。 ジャンプ テーブルは、 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
注釈
スイッチ テーブルを出力します。
命令値は、 OpCodes 列挙型で定義されます。
ラベルは DefineLabel を使用して作成され、ストリーム内の位置は MarkLabelを使用して固定されます。 1 バイト命令を使用する場合、ラベルはストリームに沿って最大 127 バイトのジャンプを表すことができます。
opcode は分岐命令を表す必要があります。 分岐は相対命令であるため、 label は修正プロセス中に分岐への正しいオフセットに置き換えられます。
適用対象
Emit(OpCode, MethodInfo)
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
指定した命令を、Microsoft中間言語 (MSIL) ストリームの後に、指定されたメソッドのメタデータ トークンを配置します。
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)
パラメーター
- opcode
- OpCode
ストリームに出力される MSIL 命令。
- meth
- MethodInfo
メソッドを表す MethodInfo 。
例外
meth は nullです。
meth は、 IsGenericMethodDefinition プロパティが falseされるジェネリック メソッドです。
注釈
命令値は、 OpCodes 列挙型で定義されます。
モジュールをポータブル実行可能ファイル (PE) ファイルに永続化するときに、必要に応じて命令ストリームに修正プログラムを適用できるように、 meth の場所が記録されます。
methがジェネリック メソッドを表す場合は、ジェネリック メソッド定義である必要があります。 つまり、 その MethodInfo.IsGenericMethodDefinition プロパティは trueする必要があります。
適用対象
Emit(OpCode, ConstructorInfo)
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
指定したコンストラクターの指定した命令とメタデータ トークンを、命令のMicrosoft中間言語 (MSIL) ストリームに配置します。
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::ConstructorInfo ^ con);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::ConstructorInfo ^ con);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.ConstructorInfo con);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.ConstructorInfo con);
[System.Runtime.InteropServices.ComVisible(true)]
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.ConstructorInfo con);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit
[<System.Runtime.InteropServices.ComVisible(true)>]
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit
Public MustOverride Sub Emit (opcode As OpCode, con As ConstructorInfo)
Public Overridable Sub Emit (opcode As OpCode, con As ConstructorInfo)
パラメーター
- opcode
- OpCode
ストリームに出力される MSIL 命令。
- con
- ConstructorInfo
コンストラクターを表す ConstructorInfo 。
- 属性
例外
con は nullです。
注釈
命令値は、 OpCodes 列挙型で定義されます。
モジュールをポータブル実行可能ファイル (PE) ファイルに永続化するときに、必要に応じて命令ストリームに修正プログラムを適用できるように、 con の場所が記録されます。
適用対象
Emit(OpCode, Int64)
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
指定した命令と数値引数を、命令のMicrosoft中間言語 (MSIL) ストリームに配置します。
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)
パラメーター
- opcode
- OpCode
ストリームに配置する MSIL 命令。
- arg
- Int64
命令の直後にストリームにプッシュされる数値引数。
注釈
命令値は、 OpCodes 列挙型で定義されます。
適用対象
Emit(OpCode, Int32)
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
指定した命令と数値引数を、命令のMicrosoft中間言語 (MSIL) ストリームに配置します。
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)
パラメーター
- opcode
- OpCode
ストリームに配置する MSIL 命令。
- arg
- Int32
命令の直後にストリームにプッシュされる数値引数。
注釈
命令値は、 OpCodes 列挙型で定義されます。
適用対象
Emit(OpCode, Int16)
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
指定した命令と数値引数を、命令のMicrosoft中間言語 (MSIL) ストリームに配置します。
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)
パラメーター
- opcode
- OpCode
ストリームに出力される MSIL 命令。
- arg
- Int16
Int引数は、命令の直後にストリームにプッシュされます。
注釈
命令値は、 OpCodes 列挙型で定義されます。
適用対象
Emit(OpCode, Double)
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
指定した命令と数値引数を、命令のMicrosoft中間言語 (MSIL) ストリームに配置します。
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)
パラメーター
- opcode
- OpCode
ストリームに配置する MSIL 命令。
OpCodes列挙体で定義されます。
- arg
- Double
命令の直後にストリームにプッシュされる数値引数。
注釈
命令値は、 OpCodes 列挙型で定義されます。
適用対象
Emit(OpCode, Byte)
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
指定した命令と文字引数を、命令のMicrosoft中間言語 (MSIL) ストリームに配置します。
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)
パラメーター
- opcode
- OpCode
ストリームに配置する MSIL 命令。
- arg
- Byte
命令の直後にストリームにプッシュされる文字引数。
注釈
命令値は、 OpCodes 列挙型で定義されます。
適用対象
Emit(OpCode)
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
指定した命令を命令のストリームに配置します。
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)
パラメーター
- opcode
- OpCode
ストリームに配置する Microsoft Intermediate Language (MSIL) 命令。
例
次のコード サンプルは、 Emit を使用して、 ILGeneratorのインスタンスを介して MSIL 出力を生成する方法を示しています。
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
注釈
opcode パラメーターに引数が必要な場合、呼び出し元は、引数の長さが宣言されたパラメーターの長さと一致することを確認する必要があります。 それ以外の場合、結果は予測できません。 たとえば、Emit 命令に 2 バイトのオペランドが必要で、呼び出し元が 4 バイトのオペランドを指定した場合、ランタイムは命令ストリームに 2 バイトを追加で出力します。 これらの余分なバイトは Nop 命令になります。
命令値は、 OpCodesで定義されます。
適用対象
Emit(OpCode, Label)
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
- ソース:
- ILGenerator.cs
指定した命令をMicrosoft中間言語 (MSIL) ストリームに配置し、修正が完了したときにラベルを含める領域を残します。
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)
パラメーター
- opcode
- OpCode
ストリームに出力される MSIL 命令。
- label
- Label
この場所から分岐するラベル。
例
次のコード サンプルは、ジャンプ テーブルを使用した動的メソッドの作成を示しています。 ジャンプ テーブルは、 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
注釈
命令値は、 OpCodes 列挙型で定義されます。
ラベルは DefineLabelを使用して作成され、ストリーム内の位置は MarkLabelを使用して固定されます。 1 バイト命令を使用する場合、ラベルはストリームに沿って最大 127 バイトのジャンプを表すことができます。
opcode は分岐命令を表す必要があります。 分岐は相対命令であるため、 label は修正プロセス中に分岐への正しいオフセットに置き換えられます。