4

System.Reflection.Emit名前空間を使用して、2D 配列構築用の IL を生成したいと考えています。

私のC#コードは

Array 2dArr  = Array.CreateInstance(typeof(int),100,100); 

を使用ildasmすると、上記の C# コードに対して次の IL コードが生成されることがわかりました。

IL_0006:  call       class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_000b:  ldc.i4.s   100
IL_000d:  ldc.i4.s   100
IL_000f:  call       class [mscorlib]System.Array [mscorlib]System.Array::CreateInstance(class [mscorlib]System.Type, 
                                                                                           int32,
                                                                                           int32)

以下に示すように、最後の 3 つの IL ステートメントを生成できました。

MethodInfo createArray = typeof(Array).GetMethod("CreateInstance",
                new Type[] { typeof(Type),typeof(int),typeof(int) });
gen.Emit(OpCodes.Ldc_I4_1);
           gen.Emit(OpCodes.Ldc_I4_1);
           gen.Emit(OpCodes.Call, createArray);

しかし、最初のILステートメントを生成する方法について明確な考えがありません(つまりIL_0006: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle))

何か考えはありますか?

さらに、誰かが System.Reflection.Emit 名前空間を使用して IL コードを生成する方法について、いくつかの優れたチュートリアル/ドキュメントを指摘できますか?

4

1 に答える 1

8

ああ、こんばんはtypeof。はい、それは:

 il.Emit(OpCodes.Ldtoken, typeof(int));
 il.EmitCall(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle"), null);

ガイダンスについて...行き詰まった場合の私のトリックは、常に「似たようなものをコンパイルし、リフレクターで見る」ことです。

いくつかの例が必要な場合は、dapper-dot-netprotobuf-netの両方が適切な量の IL を実行します。2 つ目は、全面禁止のクレイジーな IL です。

IL のヒント:

  • 画面右側のすべてのステップでコメントのスタックを追跡します
  • ブランチなどの短縮形を使用しますが、非常にローカルなブランチがあることがわかっている場合にのみ使用してください
  • 整数のロードなどの単純なことでも、ユーティリティメソッドの小さなセットを自分で作成します (値に応じて、int-32 をロードする方法が 12 通りあるため、実際には非常に複雑です)。
于 2011-06-07T05:08:59.347 に答える