3

EventHandler<EventArgsX>EventArgs から継承する型 (EventArgs1 と呼びます) と、EventArgs1 から継承するさらに多くのクラス (これらをまとめて EventArgsX と呼びます) がある場合、実行時に 型であるイベントの束これらのイベントのいずれかの EventInfo が渡されました。EventArgs1 型 (例: MyEventHandler(object sender, EventArgs1 e)) の 2 番目の引数を期待するイベント ハンドラーを追加したいのですが、どうすればよいですか?

イベントがタイプの場合、EventHandler<EventArgs1>私はこれを行うだけです:

eventInfo.AddEventHandler(this, new EventHandler<EventArgs1>(MyEventHandler));

しかし、これはイベントのタイプが である場合に例外をスローEventHandler<EventArgsX>します。コンパイル時に EventArgsX が何であるかがわからないため、コンパイル時にEventHandler<EventArgsX> ハンドラーを追加していたイベントがわかっている場合は、これを単純に新しくすることはできません。完全に受け入れられます:

MyEvent += MyEventHandler

しかし、実行時にこれを行う方法がわかりません。助言がありますか?

4

2 に答える 2

4

私は単に新しいアップすることはできませんEventHandler<EventArgsX>

Delegate.CreateDelegate()確かにできますが、リフレクションを使用して行う必要があります。MyEventHandlerが のインスタンス メソッドであると仮定すると、次のthisように実行できます。

var eventInfo = …;

EventHandler<EventArgs1> badHandler = MyEventHandler;

var goodHandler = Delegate.CreateDelegate(
    eventInfo.EventHandlerType, this, badHandler.Method);

eventInfo.AddEventHandler(this, goodHandler);
于 2012-04-19T22:20:19.013 に答える
0

アップデート

基本的に、質問を逆に読みました。逆のことをしようとしている他の誰かがこの質問を見つけ場合に備えて、この回答を残します。


基本的に、やろうとしていることはできません。デリゲートの EventArgs 型がイベントの宣言された型のサブクラスである場合、イベントはデリゲートを追加できません。入力パラメーターが反変の場合、共分散を使用しようとしています。

これらのクラスを想定

class EventArgs1 : EventArgs {}
class EventArgsA : EventArgs1 {}
class EventArgsB : EventArgs1 {}

void Handle(object sender, EventArgsA args)署名付きのイベントにメソッドを追加できたらどうなるか考えてみてくださいvoid SomeEvent(object sender, EventArgs1 args)。イベント ソースは次のようにします。

if (SomeEvent != null)
{
    var args = new EventArgsB();
    SomeEvent(this, args);      //this line is perfectly legal, as EventArgsB inherits from EventArgs1.
}

ただし、ランタイムがイベントの呼び出しリストでこのデリゲートに到達すると、argsオブジェクトをに渡す必要がありますがHandle(object, EventArgsA)、これはもちろんできません。これは、EventArgsB インスタンスが EventArgsA インスタンスではないためです。実行時例外が発生します。実際には、デリゲートを追加すると不一致がキャッチされるため、例外がスローされます。

于 2012-04-19T22:19:52.917 に答える