基本的には、イベント名を文字列として受け入れて、EventInfo
を取得します。次に、リフレクションを使用してイベントハンドラの型とイベントの引数型を発見し、その型の新しいデリゲート(myEventHandler
)を作成し、イベントにフックします。いつまでかmyEventHandler
が呼び出されると、私はダウンキャストして、引数をハンドラに渡す必要があります。ILデリゲートインスタンスを呼び出すために発行しますか?
私のコードは以下の通りです。 「ハンドラ」はmyEventHandler
によって呼び出される必要があります。いつでも「d」が呼び出されます。私はいくつかのReflectionをそこに置く必要がありますコードをどこに置くか?何かご意見は?
EventHandler handler = delegate(object sender, EventArgs eventArgs)
{
//something will happen here
};
Type[] typeArgs = { typeof(object), derivedEventArgsType };
DynamicMethod myEventHandler = new DynamicMethod("", typeof(void), typeArgs);
var ilgen = myEventHandler.GetILGenerator();
//What should be the IL code here to
//cast derviedEventArgs to EventArgs and
//invoke the 'handler' above??????
ilgen.Emit(OpCodes.Pop);
ilgen.Emit(OpCodes.Ret);
Delegate d = dynamic.CreateDelegate(derviedEventHandlerType);
//addMethod is the add MethodInfo for an Event
addMethod.Invoke(target, new object[] { d });
編集:リフレクターを介した観察に基づいて。
反射手動符号化されたシナリオのためのコードを生成
.method public hidebysig instance void <Main>b__1(object sender, class ConsoleApplication2.MyEventArgs e) cil managed
{
.maxstack 8
L_0000: nop
L_0001: ldarg.0
L_0002: ldfld class [mscorlib]System.EventHandler ConsoleApplication2.Program/<>c__DisplayClass3::handler
L_0007: ldarg.1
L_0008: ldarg.2
L_0009: callvirt instance void [mscorlib]System.EventHandler::Invoke(object, class [mscorlib]System.EventArgs)
L_000e: nop
L_000f: ret
}
であり、これは、私はそれに基づいてしようとしたものです。
ilgen.Emit(OpCodes.Nop);
ilgen.Emit(OpCodes.Ldarg_0);
ilgen.Emit(OpCodes.Ldfld,eh.GetType().GetField("handler"));
ilgen.Emit(OpCodes.Ldarg_1);
ilgen.Emit(OpCodes.Ldarg_2);
ilgen.EmitCall(OpCodes.Callvirt,eh.handler.Method,
new Type[]{ typeof(object), typeof(EventArgs) });
ilgen.Emit(OpCodes.Nop);
ilgen.Emit(OpCodes.Ret);
しかし、これは、実行時エラーの原因となっている:
'Calling convention must be varargs'
たぶん私は何かが欠けていますが、ILに優れた外観を持っている必要があります。
ここでのトリックは、常にC#で必要なコードを記述し、ILを見るためにリフレクタ/ ILDASMを使用することです。私はld、castclass、そしてcallvirtの組み合わせを推測するだろう –
すごく合意した。私はそのルートを取っているだろうが、どんなリフレクションもそうではないかと思っていたので、Ninjasはすぐにこれを指摘するかもしれない。 – amazedsaint
もう一度見て - "ハンドラ"はどこにあるの? argsと比較して?私はそれを一緒にするのは苦痛になるだろうと思っています。 C#のバージョンではキャプチャクラスが使用されているようですが、動的メソッドは静的なので、どんな状態でも押し込むことはありません。 –