6

私ができる変数を持つメソッドを発行したいと思います。しかし、その変数に別の (発行されていない) メソッドへの参照である MethodInfo オブジェクトを格納したいと思います。

typeof(someClass).GetMethod(...) を呼び出すオペコードを発行することもできますが、この MethodInfo のトークンを単純にロードして変数に直接焼き付けることができれば、より効率的です。

つまり、言い換えると、「オブジェクトのロード」オペコードと言って、実行時にスタックにロードされるオブジェクトを発行時に渡しましょう。(これを試したところ、OpCodes.Ldobj で何らかのエラーが発生しました)。または、実行時にこれを行うオペコードを発行する必要がありますか?

4

1 に答える 1

10

一般的なオブジェクトをILに格納する方法がないため、一般的なオブジェクトをILにロードすることはできません(のようないくつかの特殊なタイプを除くstring)。シリアル化を使用して(それをサポートするタイプの場合)それを回避することはできますが、それはあなたが望んでいることではないと思います。また、ldobjまったく異なる目的を果たします。

ただし、これは、C#がオペレーターMethodInfoに対して行うのと非常によく似た方法で行うことができます。typeofつまり、次のことを意味します。

  1. ldtoken命令を使用してRuntimeMethodHandle
  2. MethodBase.GetMethodFromHandle()取得するために呼び出すMethodBase
  3. にキャストMethodInfo

を返すメソッドを生成するコード全体は、次のMethodInfoようになります。

MethodInfo loadedMethod = …;
var getMethodMethod = typeof(MethodBase).GetMethod(
    "GetMethodFromHandle", new[] { typeof(RuntimeMethodHandle) });

var createdMethod = new DynamicMethod(
    "GetMethodInfo", typeof(MethodInfo), Type.EmptyTypes);

var il = createdMethod.GetILGenerator();
il.Emit(OpCodes.Ldtoken, loadedMethod);
il.Emit(OpCodes.Call, getMethodMethod);
il.Emit(OpCodes.Castclass, typeof(MethodInfo));
il.Emit(OpCodes.Ret);

var func = (Func<MethodInfo>)createdMethod.CreateDelegate(typeof(Func<MethodInfo>));
Console.WriteLine(func());
于 2013-02-10T13:10:14.797 に答える