1

ここでの私の質問のフォローアップとして、実行時にパラメーターが決定される匿名のイベントハンドラーを作成しようとしています。

private void RegisterEventHandlers(Control ctl)
{
  foreach (Command command in CommandList)
  {
    EventInfo eventInfo = ctl.GetType().GetEvent(command.Name);

    List<ParameterExpression> callArguments = new List<ParameterExpression>();
    foreach (ParameterInfo parameter in eventInfo.EventHandlerType.GetMethod("Invoke").GetParameters())
    {
      callArguments.Add(Expression.Parameter(parameter.ParameterType, parameter.Name));
    }

    //begin pseudo code
    method = (callArguments) => 
    {
      if (sender != null) ...
      if (e != null) ...
      name = command.name;
    };
    or
    method = new delegate
    {
      if (sender != null) ...
      if (e != null) ...
      name = command.name;
    };
    //end pseudo code

    var body = Expression.Call(Expression.Constant(this), method, callArguments);
    var lambda = Expression.Lambda(eventInfo.EventHandlerType, body, callArguments);

    eventInfo.AddEventHandler(ctl, lambda.Compile());
  }
}

ラムダ式とデリゲートに関する知識が不足しているため、この問題を解決できません...

匿名ハンドラーは、送信者オブジェクト、イベント引数、およびコマンドオブジェクトを別の関数に転送するだけです。すべてのイベントが同じ引数を持っているわけではないので、ハンドラーを動的引数を持つ無名関数として定義することを考えました。

しかし、私の問題に取り組む可能性のある他の解決策は大歓迎です。

4

1 に答える 1

0

デリゲート/ラムダを params 配列として宣言できます。

method = delegate(params object[] args)
{
    ...
};

その内部で MethodInfo クラスを使用して、引数の転送先のメソッドに関する情報を取得します。

しかし、あなたはここでダイナミックになりすぎていると思います。リフレクションを使用すると、コンパイル時の機能を使用するときに必要な通常の抽象化メカニズムをバイパスできます。これにより、複雑さが増し、可読性が失われ、多くのコンパイル時エラーが実行時エラーに変わります。可読性とコンパイル時の型安全性を維持しながら、ポリモーフィズムとデリゲートを使用して実行時に何かを決定することもできます。Microsoft は、ライブラリ全体でこれを行います。System.Reflection 名前空間の実際の実装を除いて、リフレクションの使用を必要とするライブラリは見当たりません。

于 2013-03-18T13:46:20.513 に答える