DynamicMethodとILGeneratorを使用してC#で動的なイベント生成

StackOverflow https://stackoverflow.com/questions/674728

  •  21-08-2019
  •  | 
  •  

質問

私は、実行時にEventInfoオブジェクトに基づいて、イベントハンドラを生成し、そのイベントハンドラ内でメソッドを呼び出す必要があります。以下のような何かます:

public void RegisterAction(ActionData actionData, EventInfo eventInfo, 
    Control control)
{
    MethodInfo methodInfo = eventInfo.EventHandlerType.GetMethod("Invoke");

    List<Type> ps = new List<Type>();
    foreach (ParameterInfo info in methodInfo.GetParameters())
    {
        ps.Add(info.ParameterType);
    }

     DynamicMethod method = new DynamicMethod("Adapter",
                                              typeof (void),
                                              ps.ToArray(),
                                              GetType(), 
                                              true);

     ILGenerator generator = method.GetILGenerator();

     // Here I need to generate a method to do the following:
     // ExecuteAction(actionData);

     // Then I can use this runtime method as an event handler and
     // bind it to the control
     Delegate proxy = method.CreateDelegate(eventInfo.EventHandlerType, this);

     eventInfo.AddEventHandler(control, proxy);
}

私はコメント部分のILコードを生成する際の助けを必要とします。

役に立ちましたか?

解決

public void RegisterAction(ActionData actionData, EventInfo eventInfo, 
    Control control)
{
    MethodInfo methodInfo = eventInfo.EventHandlerType.GetMethod("Invoke");

    List<Type> ps = new List<Type>();
    ps.Add  (typeof (ActionData)) ;
    foreach (ParameterInfo info in methodInfo.GetParameters())
    {
        ps.Add(info.ParameterType);
    }

     DynamicMethod method = new DynamicMethod("Adapter",
                                              typeof (void),
                                              ps.ToArray(),
                                              GetType(), 
                                              true);

     // compatible signatures for ExecuteAction
     // (assuming you aren't interested in sender and eventArgs):
     // static void ExecuteAction (ActionData) ;
     // void ActionData.ExecuteAction () ;
     MethodInfo miExecuteAction = <...> ;
     ILGenerator generator = method.GetILGenerator();
     generator.Emit (OpCodes.Ldarg_0) ;
     generator.Emit (OpCodes.Call, miExecuteAction) ;
     generator.Emit (OpCodes.Ret) ;

     // if you want to pass this to ExecuteAction, 
     // you'll need to put it into actionData.
     Delegate proxy = method.CreateDelegate(eventInfo.EventHandlerType, actionData);

     eventInfo.AddEventHandler(control, proxy);
}

編集:すべてのイベントは(送信者、引数)パターンに従うならば、あなたもSREと混乱を行う必要はありませんが、考えてみると:

public static void Execute<T> (ActionData data, object sender, T args)
    where T : EventArgs
{
    ExecuteAction (data) ;
}

public void RegisterAction (ActionData actionData, EventInfo eventInfo, 
    Control control)
{
    MethodInfo compatibleMethod = typeof (this).GetMethod ("Execute",
        BindingFlags.Static | BindingFlags.Public).MakeGenericMethod (
        eventInfo.EventHandlerType.GetMethod ("Invoke").GetParameters ()[1].ParameterType)) ;
    eventInfo.AddEventHandler (control, 
        Delegate.CreateDelegate (eventInfo.EventHandlerType, actionData,
        compatibleMethod)) ;
}

他のヒント

私はあなたのイベントのMETHODINFOからデリゲートを作りたい推測している...

もしそうなら、ここにどのように説明しの記事がありますこれについては行きます。必要なILコードはその記事で説明されています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top