ILGenerator.Emit ILGenerator.Emit ILGenerator.Emit Method

定義

ジャスト イン タイム (JIT: Just In Time) コンパイラの MSIL (Microsoft Intermediate Language) ストリームに命令を書き込みます。Puts an instruction onto the Microsoft Intermediate Language (MSIL) stream for the just-in-time (JIT) compiler.

オーバーロード

Emit(OpCode, Type) Emit(OpCode, Type) Emit(OpCode, Type)

指定された命令を MSIL ストリームに書き込み、その後ろに指定された型のメタデータ トークンを書き込みます。Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given type.

Emit(OpCode, String) Emit(OpCode, String) Emit(OpCode, String)

指定された命令を MSIL ストリームに書き込み、その後ろに指定された文字列のメタデータ トークンを書き込みます。Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given string.

Emit(OpCode, Single) Emit(OpCode, Single) Emit(OpCode, Single)

命令の MSIL (Microsoft Intermediate Language) ストリームに、指定した命令と数値引数を書き込みます。Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, SByte) Emit(OpCode, SByte) Emit(OpCode, SByte)

命令の MSIL (Microsoft Intermediate Language) ストリームに、指定した命令と文字引数を書き込みます。Puts the specified instruction and character argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, FieldInfo) Emit(OpCode, FieldInfo) Emit(OpCode, FieldInfo)

命令の MSIL (Microsoft Intermediate Language) ストリームに、指定したフィールドの指定した命令とメタデータ トークンを書き込みます。Puts the specified instruction and metadata token for the specified field onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, SignatureHelper) Emit(OpCode, SignatureHelper) Emit(OpCode, SignatureHelper)

命令の MSIL (Microsoft Intermediate Language) ストリームに、指定した命令とシグネチャ トークンを書き込みます。Puts the specified instruction and a signature token onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, LocalBuilder) Emit(OpCode, LocalBuilder) Emit(OpCode, LocalBuilder)

指定された命令を MSIL (Microsoft Intermediate Language) ストリームに書き込み、その後ろに指定されたローカル変数のインデックスを書き込みます。Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the index of the given local variable.

Emit(OpCode, Label[]) Emit(OpCode, Label[]) Emit(OpCode, Label[])

指定された命令を MSIL (Microsoft Intermediate Language) ストリームに書き込み、位置を確定した後でラベルを格納する領域を残します。Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream and leaves space to include a label when fixes are done.

Emit(OpCode, MethodInfo) Emit(OpCode, MethodInfo) Emit(OpCode, MethodInfo)

指定された命令を MSIL ストリームに書き込み、その後ろに指定されたメソッドのメタデータ トークンを書き込みます。Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given method.

Emit(OpCode, ConstructorInfo) Emit(OpCode, ConstructorInfo) Emit(OpCode, ConstructorInfo)

命令の MSIL (Microsoft Intermediate Language) ストリームに、指定したコンストラクターの指定した命令とメタデータ トークンを書き込みます。Puts the specified instruction and metadata token for the specified constructor onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, Int64) Emit(OpCode, Int64) Emit(OpCode, Int64)

命令の MSIL (Microsoft Intermediate Language) ストリームに、指定した命令と数値引数を書き込みます。Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, Int32) Emit(OpCode, Int32) Emit(OpCode, Int32)

命令の MSIL (Microsoft Intermediate Language) ストリームに、指定した命令と数値引数を書き込みます。Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, Int16) Emit(OpCode, Int16) Emit(OpCode, Int16)

命令の MSIL (Microsoft Intermediate Language) ストリームに、指定した命令と数値引数を書き込みます。Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, Double) Emit(OpCode, Double) Emit(OpCode, Double)

命令の MSIL (Microsoft Intermediate Language) ストリームに、指定した命令と数値引数を書き込みます。Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode, Byte) Emit(OpCode, Byte) Emit(OpCode, Byte)

命令の MSIL (Microsoft Intermediate Language) ストリームに、指定した命令と文字引数を書き込みます。Puts the specified instruction and character argument onto the Microsoft intermediate language (MSIL) stream of instructions.

Emit(OpCode) Emit(OpCode) Emit(OpCode)

指定された命令を命令のストリームに書き込みます。Puts the specified instruction onto the stream of instructions.

Emit(OpCode, Label) Emit(OpCode, Label) Emit(OpCode, Label)

指定された命令を MSIL (Microsoft Intermediate Language) ストリームに書き込み、位置を確定した後でラベルを格納する領域を残します。Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream and leaves space to include a label when fixes are done.

Emit(OpCode, Type) Emit(OpCode, Type) Emit(OpCode, Type)

指定された命令を MSIL ストリームに書き込み、その後ろに指定された型のメタデータ トークンを書き込みます。Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given type.

public:
 virtual 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
override this.Emit : System.Reflection.Emit.OpCode * Type -> unit

パラメーター

opcode
OpCode OpCode OpCode

ストリームに書き込む MSIL 命令。The MSIL instruction to be put onto the stream.

cls
Type Type Type

TypeA Type.

例外

注釈

命令の値が定義されている、OpCodes列挙体。The instruction values are defined in the OpCodes enumeration. 場所clsトークン パッチを適用できるために必要な場合、ポータブル実行可能 (PE) ファイルには、モジュールを保持するときにするために記録されます。The location of cls is recorded so that the token can be patched if necessary when persisting the module to a portable executable (PE) file.

Emit(OpCode, String) Emit(OpCode, String) Emit(OpCode, String)

指定された命令を MSIL ストリームに書き込み、その後ろに指定された文字列のメタデータ トークンを書き込みます。Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given string.

public:
 virtual void Emit(System::Reflection::Emit::OpCode opcode, System::String ^ str);
public virtual void Emit (System.Reflection.Emit.OpCode opcode, string str);
abstract member Emit : System.Reflection.Emit.OpCode * string -> unit
override this.Emit : System.Reflection.Emit.OpCode * string -> unit

パラメーター

opcode
OpCode OpCode OpCode

ストリームに生成する MSIL 命令。The MSIL instruction to be emitted onto the stream.

str
String String String

生成する StringThe String to be emitted.

注釈

命令の値が定義されている、OpCodes列挙体。The instruction values are defined in the OpCodes enumeration. 場所strモジュールが、ポータブル実行可能 (PE) ファイルに保存された場合に将来のフィックス アップを記録します。The location of str is recorded for future fixups if the module is persisted to a portable executable (PE) file.

Emit(OpCode, Single) Emit(OpCode, Single) Emit(OpCode, Single)

命令の MSIL (Microsoft Intermediate Language) ストリームに、指定した命令と数値引数を書き込みます。Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

public:
 virtual 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
override this.Emit : System.Reflection.Emit.OpCode * single -> unit

パラメーター

opcode
OpCode OpCode OpCode

ストリームに書き込む MSIL 命令。The MSIL instruction to be put onto the stream.

arg
Single Single Single

命令の直後にストリームに格納する Single 引数。The Single argument pushed onto the stream immediately after the instruction.

注釈

命令の値が定義されている、OpCodes列挙体。The instruction values are defined in the OpCodes enumeration.

Emit(OpCode, SByte) Emit(OpCode, SByte) Emit(OpCode, SByte)

重要

この API は CLS 準拠ではありません。

命令の MSIL (Microsoft Intermediate Language) ストリームに、指定した命令と文字引数を書き込みます。Puts the specified instruction and character argument onto the Microsoft intermediate language (MSIL) stream of instructions.

public:
 void Emit(System::Reflection::Emit::OpCode opcode, System::SByte arg);
[System.CLSCompliant(false)]
public void Emit (System.Reflection.Emit.OpCode opcode, sbyte arg);
member this.Emit : System.Reflection.Emit.OpCode * sbyte -> unit

パラメーター

opcode
OpCode OpCode OpCode

ストリームに書き込む MSIL 命令。The MSIL instruction to be put onto the stream.

arg
SByte SByte SByte

命令の直後にストリームに書き込む文字引数。The character argument pushed onto the stream immediately after the instruction.

注釈

命令の値が定義されている、OpCodes列挙体。The instruction values are defined in the OpCodes enumeration.

Emit(OpCode, FieldInfo) Emit(OpCode, FieldInfo) Emit(OpCode, FieldInfo)

命令の MSIL (Microsoft Intermediate Language) ストリームに、指定したフィールドの指定した命令とメタデータ トークンを書き込みます。Puts the specified instruction and metadata token for the specified field onto the Microsoft intermediate language (MSIL) stream of instructions.

public:
 virtual 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
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.FieldInfo -> unit

パラメーター

opcode
OpCode OpCode OpCode

ストリームに生成する MSIL 命令。The MSIL instruction to be emitted onto the stream.

field
FieldInfo FieldInfo FieldInfo

フィールドを表す FieldInfoA FieldInfo representing a field.

注釈

命令の値が定義されている、OpCodes列挙体。The instruction values are defined in the OpCodes enumeration. 場所field命令ストリーム パッチを適用できるために必要な場合、ポータブル実行可能 (PE) ファイルには、モジュールを保持するときにするために記録されます。The location of field is recorded so that the instruction stream can be patched if necessary when persisting the module to a portable executable (PE) file.

Emit(OpCode, SignatureHelper) Emit(OpCode, SignatureHelper) Emit(OpCode, SignatureHelper)

命令の MSIL (Microsoft Intermediate Language) ストリームに、指定した命令とシグネチャ トークンを書き込みます。Puts the specified instruction and a signature token onto the Microsoft intermediate language (MSIL) stream of instructions.

public:
 virtual 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
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.SignatureHelper -> unit

パラメーター

opcode
OpCode OpCode OpCode

ストリームに生成する MSIL 命令。The MSIL instruction to be emitted onto the stream.

signature
SignatureHelper SignatureHelper SignatureHelper

シグネチャ トークンを構築するヘルパー。A helper for constructing a signature token.

例外

signaturenullです。signature is null.

注釈

命令の値が定義されている、OpCodes列挙体。The instruction values are defined in the OpCodes enumeration.

Emit(OpCode, LocalBuilder) Emit(OpCode, LocalBuilder) Emit(OpCode, LocalBuilder)

指定された命令を MSIL (Microsoft Intermediate Language) ストリームに書き込み、その後ろに指定されたローカル変数のインデックスを書き込みます。Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the index of the given local variable.

public:
 virtual 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
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.LocalBuilder -> unit

パラメーター

opcode
OpCode OpCode OpCode

ストリームに生成する MSIL 命令。The MSIL instruction to be emitted onto the stream.

local
LocalBuilder LocalBuilder LocalBuilder

ローカル変数。A local variable.

例外

local パラメーターの親メソッドが、この ILGenerator に関連付けられたメソッドと一致しません。The parent method of the local parameter does not match the method associated with this ILGenerator.

localnullです。local is null.

opcode は 1 バイトの命令で、localByte.MaxValue を超えるインデックスのローカル変数を表します。opcode is a single-byte instruction, and local represents a local variable with an index greater than Byte.MaxValue.

注釈

命令の値が定義されている、OpCodes列挙体。The instruction values are defined in the OpCodes enumeration.

Emit(OpCode, Label[]) Emit(OpCode, Label[]) Emit(OpCode, Label[])

指定された命令を MSIL (Microsoft Intermediate Language) ストリームに書き込み、位置を確定した後でラベルを格納する領域を残します。Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream and leaves space to include a label when fixes are done.

public:
 virtual void Emit(System::Reflection::Emit::OpCode opcode, cli::array <System::Reflection::Emit::Label> ^ labels);
public virtual void Emit (System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label[] labels);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label[] -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label[] -> unit

パラメーター

opcode
OpCode OpCode OpCode

ストリームに生成する MSIL 命令。The MSIL instruction to be emitted onto the stream.

labels
Label[]

この位置から分岐するラベル オブジェクトの配列。The array of label objects to which to branch from this location. すべてのラベルが使用されます。All of the labels will be used.

例外

connullです。con is null. この例外は、.NET Framework 4.NET Framework 4 の新しい例外です。This exception is new in the .NET Framework 4.NET Framework 4.

ジャンプ テーブルを使用する動的メソッドの作成の方法を次のコード例に示します。The code sample below illustrates the creation of a dynamic method with a jump table. 配列を使用してジャンプ テーブルを構築Labelします。The jump table is built using an array of Label.

using namespace System;
using namespace System::Threading;
using namespace System::Reflection;
using namespace System::Reflection::Emit;
Type^ BuildMyType()
{
   AppDomain^ myDomain = Thread::GetDomain();
   AssemblyName^ myAsmName = gcnew AssemblyName;
   myAsmName->Name = "MyDynamicAssembly";
   AssemblyBuilder^ myAsmBuilder = myDomain->DefineDynamicAssembly( myAsmName, AssemblyBuilderAccess::Run );
   ModuleBuilder^ myModBuilder = myAsmBuilder->DefineDynamicModule( "MyJumpTableDemo" );
   TypeBuilder^ myTypeBuilder = myModBuilder->DefineType( "JumpTableDemo", TypeAttributes::Public );
   array<Type^>^temp0 = {int::typeid};
   MethodBuilder^ myMthdBuilder = myTypeBuilder->DefineMethod( "SwitchMe", static_cast<MethodAttributes>(MethodAttributes::Public | MethodAttributes::Static), String::typeid, temp0 );
   ILGenerator^ myIL = myMthdBuilder->GetILGenerator();
   Label defaultCase = myIL->DefineLabel();
   Label endOfMethod = myIL->DefineLabel();
   
   // We are initializing our jump table. Note that the labels
   // will be placed later using the MarkLabel method.
   array<Label>^jumpTable = gcnew array<Label>(5);
   jumpTable[ 0 ] = myIL->DefineLabel();
   jumpTable[ 1 ] = myIL->DefineLabel();
   jumpTable[ 2 ] = myIL->DefineLabel();
   jumpTable[ 3 ] = myIL->DefineLabel();
   jumpTable[ 4 ] = myIL->DefineLabel();
   
   // arg0, the number we passed, is pushed onto the stack.
   // In this case, due to the design of the code sample,
   // the value pushed onto the stack happens to match the
   // index of the label (in IL terms, the index of the offset
   // in the jump table). If this is not the case, such as
   // when switching based on non-integer values, rules for the correspondence
   // between the possible case values and each index of the offsets
   // must be established outside of the ILGenerator::Emit calls,
   // much as a compiler would.
   myIL->Emit( OpCodes::Ldarg_0 );
   myIL->Emit( OpCodes::Switch, jumpTable );
   
   // Branch on default case
   myIL->Emit( OpCodes::Br_S, defaultCase );
   
   // Case arg0 = 0
   myIL->MarkLabel( jumpTable[ 0 ] );
   myIL->Emit( OpCodes::Ldstr, "are no bananas" );
   myIL->Emit( OpCodes::Br_S, endOfMethod );
   
   // Case arg0 = 1
   myIL->MarkLabel( jumpTable[ 1 ] );
   myIL->Emit( OpCodes::Ldstr, "is one banana" );
   myIL->Emit( OpCodes::Br_S, endOfMethod );
   
   // Case arg0 = 2
   myIL->MarkLabel( jumpTable[ 2 ] );
   myIL->Emit( OpCodes::Ldstr, "are two bananas" );
   myIL->Emit( OpCodes::Br_S, endOfMethod );
   
   // Case arg0 = 3
   myIL->MarkLabel( jumpTable[ 3 ] );
   myIL->Emit( OpCodes::Ldstr, "are three bananas" );
   myIL->Emit( OpCodes::Br_S, endOfMethod );
   
   // Case arg0 = 4
   myIL->MarkLabel( jumpTable[ 4 ] );
   myIL->Emit( OpCodes::Ldstr, "are four bananas" );
   myIL->Emit( OpCodes::Br_S, endOfMethod );
   
   // Default case
   myIL->MarkLabel( defaultCase );
   myIL->Emit( OpCodes::Ldstr, "are many bananas" );
   myIL->MarkLabel( endOfMethod );
   myIL->Emit( OpCodes::Ret );
   return myTypeBuilder->CreateType();
}

int main()
{
   Type^ myType = BuildMyType();
   Console::Write( "Enter an integer between 0 and 5: " );
   int theValue = Convert::ToInt32( Console::ReadLine() );
   Console::WriteLine( "---" );
   Object^ myInstance = Activator::CreateInstance( myType, gcnew array<Object^>(0) );
   array<Object^>^temp1 = {theValue};
   Console::WriteLine( "Yes, there {0} today!", myType->InvokeMember( "SwitchMe", BindingFlags::InvokeMethod, nullptr, myInstance, temp1 ) );
}


using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;

class DynamicJumpTableDemo

{

   public static Type BuildMyType()
   {
	AppDomain myDomain = Thread.GetDomain();
	AssemblyName myAsmName = new AssemblyName();
	myAsmName.Name = "MyDynamicAssembly";

	AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
						myAsmName,
						AssemblyBuilderAccess.Run);
	ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(
						"MyJumpTableDemo");

	TypeBuilder myTypeBuilder = myModBuilder.DefineType("JumpTableDemo",
							TypeAttributes.Public);
	MethodBuilder myMthdBuilder = myTypeBuilder.DefineMethod("SwitchMe", 
				             MethodAttributes.Public |
				             MethodAttributes.Static,
                                             typeof(string), 
                                             new Type[] {typeof(int)});

	ILGenerator myIL = myMthdBuilder.GetILGenerator();

	Label defaultCase = myIL.DefineLabel();	
	Label endOfMethod = myIL.DefineLabel();	

	// We are initializing our jump table. Note that the labels
	// will be placed later using the MarkLabel method. 

	Label[] jumpTable = new Label[] { myIL.DefineLabel(),
					  myIL.DefineLabel(),
					  myIL.DefineLabel(),
					  myIL.DefineLabel(),
					  myIL.DefineLabel() };

	// arg0, the number we passed, is pushed onto the stack.
	// In this case, due to the design of the code sample,
	// the value pushed onto the stack happens to match the
	// index of the label (in IL terms, the index of the offset
	// in the jump table). If this is not the case, such as
	// when switching based on non-integer values, rules for the correspondence
	// between the possible case values and each index of the offsets
	// must be established outside of the ILGenerator.Emit calls,
	// much as a compiler would.

	myIL.Emit(OpCodes.Ldarg_0);
	myIL.Emit(OpCodes.Switch, jumpTable);
	
	// Branch on default case
	myIL.Emit(OpCodes.Br_S, defaultCase);

	// Case arg0 = 0
	myIL.MarkLabel(jumpTable[0]); 
	myIL.Emit(OpCodes.Ldstr, "are no bananas");
	myIL.Emit(OpCodes.Br_S, endOfMethod);

	// Case arg0 = 1
	myIL.MarkLabel(jumpTable[1]); 
	myIL.Emit(OpCodes.Ldstr, "is one banana");
	myIL.Emit(OpCodes.Br_S, endOfMethod);

	// Case arg0 = 2
	myIL.MarkLabel(jumpTable[2]); 
	myIL.Emit(OpCodes.Ldstr, "are two bananas");
	myIL.Emit(OpCodes.Br_S, endOfMethod);

	// Case arg0 = 3
	myIL.MarkLabel(jumpTable[3]); 
	myIL.Emit(OpCodes.Ldstr, "are three bananas");
	myIL.Emit(OpCodes.Br_S, endOfMethod);

	// Case arg0 = 4
	myIL.MarkLabel(jumpTable[4]); 
	myIL.Emit(OpCodes.Ldstr, "are four bananas");
	myIL.Emit(OpCodes.Br_S, endOfMethod);

	// Default case
	myIL.MarkLabel(defaultCase);
	myIL.Emit(OpCodes.Ldstr, "are many bananas");

	myIL.MarkLabel(endOfMethod);
	myIL.Emit(OpCodes.Ret);
	
	return myTypeBuilder.CreateType();

   }

   public static void Main()
   {
	Type myType = BuildMyType();
	
	Console.Write("Enter an integer between 0 and 5: ");
	int theValue = Convert.ToInt32(Console.ReadLine());

	Console.WriteLine("---");
	Object myInstance = Activator.CreateInstance(myType, new object[0]);	
	Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe",
			  		           BindingFlags.InvokeMethod,
			  		           null,
			  		           myInstance,
			  		           new object[] {theValue}));  
			  
   }

}


Imports System
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 'Main

End Class 'DynamicJumpTableDemo

注釈

スイッチのテーブルを出力します。Emits a switch table.

命令の値が定義されている、OpCodes列挙体。The instruction values are defined in the OpCodes enumeration.

使用してラベルが作成されたDefineLabelを使用して、ストリーム内の位置は固定とMarkLabelします。Labels are created using DefineLabel and their location within the stream is fixed by using MarkLabel. 1 バイトの命令を使用する場合、ラベルは最大で 127 バイト ストリーム内のジャンプを表すことができます。If a single-byte instruction is used, the label can represent a jump of at most 127 bytes along the stream. opcode 分岐命令を表す必要があります。opcode must represent a branch instruction. 分岐は相対的な手順については、あるためlabelは置き換えられますブランチへの正しいオフセット修正プロセス中にします。Because branches are relative instructions, label will be replaced with the correct offset to branch during the fixup process.

Emit(OpCode, MethodInfo) Emit(OpCode, MethodInfo) Emit(OpCode, MethodInfo)

指定された命令を MSIL ストリームに書き込み、その後ろに指定されたメソッドのメタデータ トークンを書き込みます。Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given method.

public:
 virtual 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
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.MethodInfo -> unit

パラメーター

opcode
OpCode OpCode OpCode

ストリームに生成する MSIL 命令。The MSIL instruction to be emitted onto the stream.

meth
MethodInfo MethodInfo MethodInfo

メソッドを表す MethodInfoA MethodInfo representing a method.

例外

meth は、IsGenericMethodDefinition プロパティが false のジェネリック メソッドです。meth is a generic method for which the IsGenericMethodDefinition property is false.

注釈

命令の値が定義されている、OpCodes列挙体。The instruction values are defined in the OpCodes enumeration.

場所meth命令ストリーム パッチを適用できるために必要な場合、ポータブル実行可能 (PE) ファイルには、モジュールを保持するときにするために記録されます。The location of meth is recorded so that the instruction stream can be patched if necessary when persisting the module to a portable executable (PE) file.

場合methジェネリックのメソッドを表すジェネリック メソッド定義する必要があります。If meth represents a generic method, it must be a generic method definition. つまり、そのMethodInfo.IsGenericMethodDefinitionプロパティである必要がありますtrueします。That is, its MethodInfo.IsGenericMethodDefinition property must be true.

Emit(OpCode, ConstructorInfo) Emit(OpCode, ConstructorInfo) Emit(OpCode, ConstructorInfo)

命令の MSIL (Microsoft Intermediate Language) ストリームに、指定したコンストラクターの指定した命令とメタデータ トークンを書き込みます。Puts the specified instruction and metadata token for the specified constructor onto the Microsoft intermediate language (MSIL) stream of instructions.

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
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit

パラメーター

opcode
OpCode OpCode OpCode

ストリームに生成する MSIL 命令。The MSIL instruction to be emitted onto the stream.

con
ConstructorInfo ConstructorInfo ConstructorInfo

コンストラクターを表す ConstructorInfoA ConstructorInfo representing a constructor.

例外

connullです。con is null. この例外は、.NET Framework 4.NET Framework 4 の新しい例外です。This exception is new in the .NET Framework 4.NET Framework 4.

注釈

命令の値が定義されている、OpCodes列挙体。The instruction values are defined in the OpCodes enumeration.

場所con命令ストリーム パッチを適用できるために必要な場合、ポータブル実行可能 (PE) ファイルには、モジュールを保持するときにするために記録されます。The location of con is recorded so that the instruction stream can be patched if necessary when persisting the module to a portable executable (PE) file.

Emit(OpCode, Int64) Emit(OpCode, Int64) Emit(OpCode, Int64)

命令の MSIL (Microsoft Intermediate Language) ストリームに、指定した命令と数値引数を書き込みます。Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

public:
 virtual 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
override this.Emit : System.Reflection.Emit.OpCode * int64 -> unit

パラメーター

opcode
OpCode OpCode OpCode

ストリームに書き込む MSIL 命令。The MSIL instruction to be put onto the stream.

arg
Int64 Int64 Int64

命令の直後のストリームに書き込まれる数値引数。The numerical argument pushed onto the stream immediately after the instruction.

注釈

命令の値が定義されている、OpCodes列挙体。The instruction values are defined in the OpCodes enumeration.

Emit(OpCode, Int32) Emit(OpCode, Int32) Emit(OpCode, Int32)

命令の MSIL (Microsoft Intermediate Language) ストリームに、指定した命令と数値引数を書き込みます。Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

public:
 virtual 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
override this.Emit : System.Reflection.Emit.OpCode * int -> unit

パラメーター

opcode
OpCode OpCode OpCode

ストリームに書き込む MSIL 命令。The MSIL instruction to be put onto the stream.

arg
Int32 Int32 Int32

命令の直後のストリームに書き込まれる数値引数。The numerical argument pushed onto the stream immediately after the instruction.

注釈

命令の値が定義されている、OpCodes列挙体。The instruction values are defined in the OpCodes enumeration.

Emit(OpCode, Int16) Emit(OpCode, Int16) Emit(OpCode, Int16)

命令の MSIL (Microsoft Intermediate Language) ストリームに、指定した命令と数値引数を書き込みます。Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

public:
 virtual 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
override this.Emit : System.Reflection.Emit.OpCode * int16 -> unit

パラメーター

opcode
OpCode OpCode OpCode

ストリームに生成する MSIL 命令。The MSIL instruction to be emitted onto the stream.

arg
Int16 Int16 Int16

命令の直後にストリームに格納する Int 引数。The Int argument pushed onto the stream immediately after the instruction.

注釈

命令の値が定義されている、OpCodes列挙体。The instruction values are defined in the OpCodes enumeration.

Emit(OpCode, Double) Emit(OpCode, Double) Emit(OpCode, Double)

命令の MSIL (Microsoft Intermediate Language) ストリームに、指定した命令と数値引数を書き込みます。Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions.

public:
 virtual 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
override this.Emit : System.Reflection.Emit.OpCode * double -> unit

パラメーター

opcode
OpCode OpCode OpCode

ストリームに書き込む MSIL 命令。The MSIL instruction to be put onto the stream. OpCodes 列挙体で定義されます。Defined in the OpCodes enumeration.

arg
Double Double Double

命令の直後のストリームに書き込まれる数値引数。The numerical argument pushed onto the stream immediately after the instruction.

注釈

命令の値が定義されている、OpCodes列挙体。The instruction values are defined in the OpCodes enumeration.

Emit(OpCode, Byte) Emit(OpCode, Byte) Emit(OpCode, Byte)

命令の MSIL (Microsoft Intermediate Language) ストリームに、指定した命令と文字引数を書き込みます。Puts the specified instruction and character argument onto the Microsoft intermediate language (MSIL) stream of instructions.

public:
 virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Byte arg);
public virtual void Emit (System.Reflection.Emit.OpCode opcode, byte arg);
abstract member Emit : System.Reflection.Emit.OpCode * byte -> unit
override this.Emit : System.Reflection.Emit.OpCode * byte -> unit

パラメーター

opcode
OpCode OpCode OpCode

ストリームに書き込む MSIL 命令。The MSIL instruction to be put onto the stream.

arg
Byte Byte Byte

命令の直後にストリームに書き込む文字引数。The character argument pushed onto the stream immediately after the instruction.

注釈

命令の値が定義されている、OpCodes列挙体。The instruction values are defined in the OpCodes enumeration.

Emit(OpCode) Emit(OpCode) Emit(OpCode)

指定された命令を命令のストリームに書き込みます。Puts the specified instruction onto the stream of instructions.

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

パラメーター

opcode
OpCode OpCode OpCode

ストリームに書き込む MSIL (Microsoft Intermediate Language) 命令。The Microsoft Intermediate Language (MSIL) instruction to be put onto the stream.

以下のコード サンプルの使用を示しますEmitのインスタンスを使用して MSIL 出力を生成するILGeneratorします。The code sample below demonstrates the use of Emit to generate MSIL output via an instance of ILGenerator.

using namespace System;
using namespace System::Threading;
using namespace System::Reflection;
using namespace System::Reflection::Emit;
Type^ BuildMyType()
{
   AppDomain^ myDomain = Thread::GetDomain();
   AssemblyName^ myAsmName = gcnew AssemblyName;
   myAsmName->Name = "MyDynamicAssembly";
   AssemblyBuilder^ myAsmBuilder = myDomain->DefineDynamicAssembly( myAsmName, AssemblyBuilderAccess::Run );
   ModuleBuilder^ myModBuilder = myAsmBuilder->DefineDynamicModule( "MyJumpTableDemo" );
   TypeBuilder^ myTypeBuilder = myModBuilder->DefineType( "JumpTableDemo", TypeAttributes::Public );
   array<Type^>^temp0 = {int::typeid};
   MethodBuilder^ myMthdBuilder = myTypeBuilder->DefineMethod( "SwitchMe", static_cast<MethodAttributes>(MethodAttributes::Public | MethodAttributes::Static), String::typeid, temp0 );
   ILGenerator^ myIL = myMthdBuilder->GetILGenerator();
   Label defaultCase = myIL->DefineLabel();
   Label endOfMethod = myIL->DefineLabel();
   
   // We are initializing our jump table. Note that the labels
   // will be placed later using the MarkLabel method.
   array<Label>^jumpTable = gcnew array<Label>(5);
   jumpTable[ 0 ] = myIL->DefineLabel();
   jumpTable[ 1 ] = myIL->DefineLabel();
   jumpTable[ 2 ] = myIL->DefineLabel();
   jumpTable[ 3 ] = myIL->DefineLabel();
   jumpTable[ 4 ] = myIL->DefineLabel();
   
   // arg0, the number we passed, is pushed onto the stack.
   // In this case, due to the design of the code sample,
   // the value pushed onto the stack happens to match the
   // index of the label (in IL terms, the index of the offset
   // in the jump table). If this is not the case, such as
   // when switching based on non-integer values, rules for the correspondence
   // between the possible case values and each index of the offsets
   // must be established outside of the ILGenerator::Emit calls,
   // much as a compiler would.
   myIL->Emit( OpCodes::Ldarg_0 );
   myIL->Emit( OpCodes::Switch, jumpTable );
   
   // Branch on default case
   myIL->Emit( OpCodes::Br_S, defaultCase );
   
   // Case arg0 = 0
   myIL->MarkLabel( jumpTable[ 0 ] );
   myIL->Emit( OpCodes::Ldstr, "are no bananas" );
   myIL->Emit( OpCodes::Br_S, endOfMethod );
   
   // Case arg0 = 1
   myIL->MarkLabel( jumpTable[ 1 ] );
   myIL->Emit( OpCodes::Ldstr, "is one banana" );
   myIL->Emit( OpCodes::Br_S, endOfMethod );
   
   // Case arg0 = 2
   myIL->MarkLabel( jumpTable[ 2 ] );
   myIL->Emit( OpCodes::Ldstr, "are two bananas" );
   myIL->Emit( OpCodes::Br_S, endOfMethod );
   
   // Case arg0 = 3
   myIL->MarkLabel( jumpTable[ 3 ] );
   myIL->Emit( OpCodes::Ldstr, "are three bananas" );
   myIL->Emit( OpCodes::Br_S, endOfMethod );
   
   // Case arg0 = 4
   myIL->MarkLabel( jumpTable[ 4 ] );
   myIL->Emit( OpCodes::Ldstr, "are four bananas" );
   myIL->Emit( OpCodes::Br_S, endOfMethod );
   
   // Default case
   myIL->MarkLabel( defaultCase );
   myIL->Emit( OpCodes::Ldstr, "are many bananas" );
   myIL->MarkLabel( endOfMethod );
   myIL->Emit( OpCodes::Ret );
   return myTypeBuilder->CreateType();
}

int main()
{
   Type^ myType = BuildMyType();
   Console::Write( "Enter an integer between 0 and 5: " );
   int theValue = Convert::ToInt32( Console::ReadLine() );
   Console::WriteLine( "---" );
   Object^ myInstance = Activator::CreateInstance( myType, gcnew array<Object^>(0) );
   array<Object^>^temp1 = {theValue};
   Console::WriteLine( "Yes, there {0} today!", myType->InvokeMember( "SwitchMe", BindingFlags::InvokeMethod, nullptr, myInstance, temp1 ) );
}


using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;

class DynamicJumpTableDemo

{

   public static Type BuildMyType()
   {
	AppDomain myDomain = Thread.GetDomain();
	AssemblyName myAsmName = new AssemblyName();
	myAsmName.Name = "MyDynamicAssembly";

	AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
						myAsmName,
						AssemblyBuilderAccess.Run);
	ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(
						"MyJumpTableDemo");

	TypeBuilder myTypeBuilder = myModBuilder.DefineType("JumpTableDemo",
							TypeAttributes.Public);
	MethodBuilder myMthdBuilder = myTypeBuilder.DefineMethod("SwitchMe", 
				             MethodAttributes.Public |
				             MethodAttributes.Static,
                                             typeof(string), 
                                             new Type[] {typeof(int)});

	ILGenerator myIL = myMthdBuilder.GetILGenerator();

	Label defaultCase = myIL.DefineLabel();	
	Label endOfMethod = myIL.DefineLabel();	

	// We are initializing our jump table. Note that the labels
	// will be placed later using the MarkLabel method. 

	Label[] jumpTable = new Label[] { myIL.DefineLabel(),
					  myIL.DefineLabel(),
					  myIL.DefineLabel(),
					  myIL.DefineLabel(),
					  myIL.DefineLabel() };

	// arg0, the number we passed, is pushed onto the stack.
	// In this case, due to the design of the code sample,
	// the value pushed onto the stack happens to match the
	// index of the label (in IL terms, the index of the offset
	// in the jump table). If this is not the case, such as
	// when switching based on non-integer values, rules for the correspondence
	// between the possible case values and each index of the offsets
	// must be established outside of the ILGenerator.Emit calls,
	// much as a compiler would.

	myIL.Emit(OpCodes.Ldarg_0);
	myIL.Emit(OpCodes.Switch, jumpTable);
	
	// Branch on default case
	myIL.Emit(OpCodes.Br_S, defaultCase);

	// Case arg0 = 0
	myIL.MarkLabel(jumpTable[0]); 
	myIL.Emit(OpCodes.Ldstr, "are no bananas");
	myIL.Emit(OpCodes.Br_S, endOfMethod);

	// Case arg0 = 1
	myIL.MarkLabel(jumpTable[1]); 
	myIL.Emit(OpCodes.Ldstr, "is one banana");
	myIL.Emit(OpCodes.Br_S, endOfMethod);

	// Case arg0 = 2
	myIL.MarkLabel(jumpTable[2]); 
	myIL.Emit(OpCodes.Ldstr, "are two bananas");
	myIL.Emit(OpCodes.Br_S, endOfMethod);

	// Case arg0 = 3
	myIL.MarkLabel(jumpTable[3]); 
	myIL.Emit(OpCodes.Ldstr, "are three bananas");
	myIL.Emit(OpCodes.Br_S, endOfMethod);

	// Case arg0 = 4
	myIL.MarkLabel(jumpTable[4]); 
	myIL.Emit(OpCodes.Ldstr, "are four bananas");
	myIL.Emit(OpCodes.Br_S, endOfMethod);

	// Default case
	myIL.MarkLabel(defaultCase);
	myIL.Emit(OpCodes.Ldstr, "are many bananas");

	myIL.MarkLabel(endOfMethod);
	myIL.Emit(OpCodes.Ret);
	
	return myTypeBuilder.CreateType();

   }

   public static void Main()
   {
	Type myType = BuildMyType();
	
	Console.Write("Enter an integer between 0 and 5: ");
	int theValue = Convert.ToInt32(Console.ReadLine());

	Console.WriteLine("---");
	Object myInstance = Activator.CreateInstance(myType, new object[0]);	
	Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe",
			  		           BindingFlags.InvokeMethod,
			  		           null,
			  		           myInstance,
			  		           new object[] {theValue}));  
			  
   }

}


Imports System
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 'Main

End Class 'DynamicJumpTableDemo

注釈

場合、opcodeパラメーターに引数が必要です、呼び出し元が引数の長さが宣言されているパラメーターの長さと一致することを確認する必要があります。If the opcode parameter requires an argument, the caller must ensure that the argument length matches the length of the declared parameter. それ以外の場合、結果は予測できません。Otherwise, results will be unpredictable. たとえば、Emit 命令が 2 バイトのオペランドを必要とし、呼び出し元が 4 バイトのオペランドする場合、ランタイムは命令ストリームに 2 つの追加のバイトを出力します。For example, if the Emit instruction requires a 2-byte operand and the caller supplies a 4-byte operand, the runtime will emit two additional bytes to the instruction stream. これらの余分なバイトになりますNop指示します。These extra bytes will be Nop instructions.

命令の値で定義されますOpCodesします。The instruction values are defined in OpCodes.

Emit(OpCode, Label) Emit(OpCode, Label) Emit(OpCode, Label)

指定された命令を MSIL (Microsoft Intermediate Language) ストリームに書き込み、位置を確定した後でラベルを格納する領域を残します。Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream and leaves space to include a label when fixes are done.

public:
 virtual 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
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label -> unit

パラメーター

opcode
OpCode OpCode OpCode

ストリームに生成する MSIL 命令。The MSIL instruction to be emitted onto the stream.

label
Label Label Label

この位置から分岐するラベル。The label to which to branch from this location.

ジャンプ テーブルを使用する動的メソッドの作成の方法を次のコード例に示します。The code sample below illustrates the creation of a dynamic method with a jump table. 配列を使用してジャンプ テーブルを構築Labelします。The jump table is built using an array of Label.

using namespace System;
using namespace System::Threading;
using namespace System::Reflection;
using namespace System::Reflection::Emit;
Type^ BuildMyType()
{
   AppDomain^ myDomain = Thread::GetDomain();
   AssemblyName^ myAsmName = gcnew AssemblyName;
   myAsmName->Name = "MyDynamicAssembly";
   AssemblyBuilder^ myAsmBuilder = myDomain->DefineDynamicAssembly( myAsmName, AssemblyBuilderAccess::Run );
   ModuleBuilder^ myModBuilder = myAsmBuilder->DefineDynamicModule( "MyJumpTableDemo" );
   TypeBuilder^ myTypeBuilder = myModBuilder->DefineType( "JumpTableDemo", TypeAttributes::Public );
   array<Type^>^temp0 = {int::typeid};
   MethodBuilder^ myMthdBuilder = myTypeBuilder->DefineMethod( "SwitchMe", static_cast<MethodAttributes>(MethodAttributes::Public | MethodAttributes::Static), String::typeid, temp0 );
   ILGenerator^ myIL = myMthdBuilder->GetILGenerator();
   Label defaultCase = myIL->DefineLabel();
   Label endOfMethod = myIL->DefineLabel();
   
   // We are initializing our jump table. Note that the labels
   // will be placed later using the MarkLabel method.
   array<Label>^jumpTable = gcnew array<Label>(5);
   jumpTable[ 0 ] = myIL->DefineLabel();
   jumpTable[ 1 ] = myIL->DefineLabel();
   jumpTable[ 2 ] = myIL->DefineLabel();
   jumpTable[ 3 ] = myIL->DefineLabel();
   jumpTable[ 4 ] = myIL->DefineLabel();
   
   // arg0, the number we passed, is pushed onto the stack.
   // In this case, due to the design of the code sample,
   // the value pushed onto the stack happens to match the
   // index of the label (in IL terms, the index of the offset
   // in the jump table). If this is not the case, such as
   // when switching based on non-integer values, rules for the correspondence
   // between the possible case values and each index of the offsets
   // must be established outside of the ILGenerator::Emit calls,
   // much as a compiler would.
   myIL->Emit( OpCodes::Ldarg_0 );
   myIL->Emit( OpCodes::Switch, jumpTable );
   
   // Branch on default case
   myIL->Emit( OpCodes::Br_S, defaultCase );
   
   // Case arg0 = 0
   myIL->MarkLabel( jumpTable[ 0 ] );
   myIL->Emit( OpCodes::Ldstr, "are no bananas" );
   myIL->Emit( OpCodes::Br_S, endOfMethod );
   
   // Case arg0 = 1
   myIL->MarkLabel( jumpTable[ 1 ] );
   myIL->Emit( OpCodes::Ldstr, "is one banana" );
   myIL->Emit( OpCodes::Br_S, endOfMethod );
   
   // Case arg0 = 2
   myIL->MarkLabel( jumpTable[ 2 ] );
   myIL->Emit( OpCodes::Ldstr, "are two bananas" );
   myIL->Emit( OpCodes::Br_S, endOfMethod );
   
   // Case arg0 = 3
   myIL->MarkLabel( jumpTable[ 3 ] );
   myIL->Emit( OpCodes::Ldstr, "are three bananas" );
   myIL->Emit( OpCodes::Br_S, endOfMethod );
   
   // Case arg0 = 4
   myIL->MarkLabel( jumpTable[ 4 ] );
   myIL->Emit( OpCodes::Ldstr, "are four bananas" );
   myIL->Emit( OpCodes::Br_S, endOfMethod );
   
   // Default case
   myIL->MarkLabel( defaultCase );
   myIL->Emit( OpCodes::Ldstr, "are many bananas" );
   myIL->MarkLabel( endOfMethod );
   myIL->Emit( OpCodes::Ret );
   return myTypeBuilder->CreateType();
}

int main()
{
   Type^ myType = BuildMyType();
   Console::Write( "Enter an integer between 0 and 5: " );
   int theValue = Convert::ToInt32( Console::ReadLine() );
   Console::WriteLine( "---" );
   Object^ myInstance = Activator::CreateInstance( myType, gcnew array<Object^>(0) );
   array<Object^>^temp1 = {theValue};
   Console::WriteLine( "Yes, there {0} today!", myType->InvokeMember( "SwitchMe", BindingFlags::InvokeMethod, nullptr, myInstance, temp1 ) );
}


using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;

class DynamicJumpTableDemo

{

   public static Type BuildMyType()
   {
	AppDomain myDomain = Thread.GetDomain();
	AssemblyName myAsmName = new AssemblyName();
	myAsmName.Name = "MyDynamicAssembly";

	AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
						myAsmName,
						AssemblyBuilderAccess.Run);
	ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(
						"MyJumpTableDemo");

	TypeBuilder myTypeBuilder = myModBuilder.DefineType("JumpTableDemo",
							TypeAttributes.Public);
	MethodBuilder myMthdBuilder = myTypeBuilder.DefineMethod("SwitchMe", 
				             MethodAttributes.Public |
				             MethodAttributes.Static,
                                             typeof(string), 
                                             new Type[] {typeof(int)});

	ILGenerator myIL = myMthdBuilder.GetILGenerator();

	Label defaultCase = myIL.DefineLabel();	
	Label endOfMethod = myIL.DefineLabel();	

	// We are initializing our jump table. Note that the labels
	// will be placed later using the MarkLabel method. 

	Label[] jumpTable = new Label[] { myIL.DefineLabel(),
					  myIL.DefineLabel(),
					  myIL.DefineLabel(),
					  myIL.DefineLabel(),
					  myIL.DefineLabel() };

	// arg0, the number we passed, is pushed onto the stack.
	// In this case, due to the design of the code sample,
	// the value pushed onto the stack happens to match the
	// index of the label (in IL terms, the index of the offset
	// in the jump table). If this is not the case, such as
	// when switching based on non-integer values, rules for the correspondence
	// between the possible case values and each index of the offsets
	// must be established outside of the ILGenerator.Emit calls,
	// much as a compiler would.

	myIL.Emit(OpCodes.Ldarg_0);
	myIL.Emit(OpCodes.Switch, jumpTable);
	
	// Branch on default case
	myIL.Emit(OpCodes.Br_S, defaultCase);

	// Case arg0 = 0
	myIL.MarkLabel(jumpTable[0]); 
	myIL.Emit(OpCodes.Ldstr, "are no bananas");
	myIL.Emit(OpCodes.Br_S, endOfMethod);

	// Case arg0 = 1
	myIL.MarkLabel(jumpTable[1]); 
	myIL.Emit(OpCodes.Ldstr, "is one banana");
	myIL.Emit(OpCodes.Br_S, endOfMethod);

	// Case arg0 = 2
	myIL.MarkLabel(jumpTable[2]); 
	myIL.Emit(OpCodes.Ldstr, "are two bananas");
	myIL.Emit(OpCodes.Br_S, endOfMethod);

	// Case arg0 = 3
	myIL.MarkLabel(jumpTable[3]); 
	myIL.Emit(OpCodes.Ldstr, "are three bananas");
	myIL.Emit(OpCodes.Br_S, endOfMethod);

	// Case arg0 = 4
	myIL.MarkLabel(jumpTable[4]); 
	myIL.Emit(OpCodes.Ldstr, "are four bananas");
	myIL.Emit(OpCodes.Br_S, endOfMethod);

	// Default case
	myIL.MarkLabel(defaultCase);
	myIL.Emit(OpCodes.Ldstr, "are many bananas");

	myIL.MarkLabel(endOfMethod);
	myIL.Emit(OpCodes.Ret);
	
	return myTypeBuilder.CreateType();

   }

   public static void Main()
   {
	Type myType = BuildMyType();
	
	Console.Write("Enter an integer between 0 and 5: ");
	int theValue = Convert.ToInt32(Console.ReadLine());

	Console.WriteLine("---");
	Object myInstance = Activator.CreateInstance(myType, new object[0]);	
	Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe",
			  		           BindingFlags.InvokeMethod,
			  		           null,
			  		           myInstance,
			  		           new object[] {theValue}));  
			  
   }

}


Imports System
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 'Main

End Class 'DynamicJumpTableDemo

注釈

命令の値が定義されている、OpCodes列挙体。The instruction values are defined in the OpCodes enumeration.

使用してラベルが作成されたDefineLabelを使用して、ストリーム内の位置は固定とMarkLabelします。Labels are created using DefineLabel, and their location within the stream is fixed by using MarkLabel. 1 バイトの命令を使用する場合、ラベルは最大で 127 バイト ストリーム内のジャンプを表すことができます。If a single-byte instruction is used, the label can represent a jump of at most 127 bytes along the stream. opcode 分岐命令を表す必要があります。opcode must represent a branch instruction. 分岐は相対的な手順については、あるためlabelは置き換えられますブランチへの正しいオフセット修正プロセス中にします。Because branches are relative instructions, label will be replaced with the correct offset to branch during the fixup process.

適用対象