この記事は機械翻訳されています。英語版の記事を表示するには、[英語] のチェック ボックスをオンにしてください。また、テキストにマウス ポインターを合わせると、ポップアップ ウィンドウに英語のテキストを表示することもできます。
翻訳
英語

OpCodes.Switch フィールド

 

公開日: 2016年10月

ジャンプ テーブルを実装します。

名前空間:   System.Reflection.Emit
アセンブリ:  mscorlib (mscorlib.dll 内)

public static readonly OpCode Switch

フィールドの値

Type: System.Reflection.Emit.OpCode

次の表に、命令の 16 進数および簡単なリファレンスの概要と共に、Microsoft 中間言語 (MSIL) アセンブリの形式を示します。

形式

アセンブリの形式

説明

45 < unsigned int32 > < int32 >... < int32 >

switch (N, t1, t2... tN)

いずれかにジャンプ N 値。

履歴の移行動作を順番には。

  1. 値は、スタックにプッシュされます。

  2. 値がスタックからポップされ、実行は値が、値によってインデックス付けされたオフセット位置にある命令に転送より小さい Nします。

switch 命令がジャンプ テーブルを実装します。 命令の形式は、 unsigned int32 ターゲットの数を表す N, と続く N int32 値を指定することは、ターゲットをジャンプします。 これらのターゲットは、これを次の命令の先頭からのオフセット (正または負の値) として表されます switch 命令します。

switch 命令がスタックから値をポップしを比較して、符号なし整数として Nします。 値の場合より小さい N, 、ターゲットが、番号が 0 からインデックスの値をターゲットに転送される実行 (値 0 は、最初のターゲットを受け取り、値 1 と 2 つ目のターゲットなど)。 値がより大きいかに等しい場合 N, 、次の命令 (フォール スルー) で実行が続行されます。

最初に制御を転送できますのみ、ターゲット命令に 1 つ以上のプレフィックス コードがある場合は、これらのプレフィックス。

制御が移りますアウトや try, 、catch, 、filter, 、および finally ブロックがこの命令によって行うことはできません。 (このような移動は厳しく制限されるは、ままにして命令を代わりに使用する必要があります。)

Emit メソッドのオーバー ロードを使用して、 switch オペコード。 Label[] 引数は、32 ビット オフセットを表すラベルの配列。

  • (オペコード、Label[]) ILGenerator.Emit

次のコード サンプルは、の使用法を示しています、 Switch の配列を使用してジャンプ テーブルを生成するオペコード 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}));  

   }

}

ユニバーサル Windows プラットフォーム
8 以降で使用可能
.NET Framework
1.1 以降で使用可能
ポータブル クラス ライブラリ
サポート対象: 移植可能 .NET プラットフォーム
Silverlight
2.0 以降で使用可能
Windows Phone Silverlight
7.1 以降で使用可能
Windows Phone
8.1 以降で使用可能
トップに戻る
表示: