イベントをリッスンしているオブジェクトを見つける方法は?
質問
イベントがあるクラスがあります:
public event MyEventHandler MyEvent;
このイベントをリッスンしているオブジェクトのコレクション(リフレクションなど)にハンドルを取得する方法はありますか?
編集-ゴールポストを移動して申し訳ありません-リフレクションbcを使用してこれを実行できるようにする必要があります 、イベント名を表す文字列値があり、リスナーを見つける必要があります。リフレクションを使用してGetInvocationListプロパティにアクセスする明白な方法がわかりません...
ありがとう!
解決
List<object> targets = MyEvent.GetInvocationList().Select(d => d.Target).ToList();
リフレクションを介してこれを行うと、残念ながら、この構文は次のようになります。
public event EventHandler MyEvent;
...
MyEvent(this, EventArgs.Empty);
は構文糖です。これが実際に行うことは:
private EventHandler compilerGeneratedName;
public event EventHandler MyEvent
{
add { compilerGeneratedName += value; }
remove { compilerGeneratedName -= value; }
}
...
compilerGeneratedName(this, EventArgs.Empty);
言い換えると、イベントには常にプロパティが最近受信した宣言的な略記があります。その結果、呼び出しリストを取得するには、コンパイラーによって名前が付けられたプライベート変数を検査する必要があります(もちろん、自分で長文構文を使用して know インスタンス変数の名前)。
event
をバッキング変数に結び付ける直接的な方法がある以上、外部に公開されたproperty
コンストラクトをバッキングハンドラに関連付ける直接的な方法はありません。つまり、は必ずしも必要ではないからです1対1の関係。ある可能性は非常に高いですが、原則としてそのようにする必要はありません。
リフレクションを使用して、イベントを宣言する型の適切なEventHandler<>
型のプライベート変数を検査できます(特定の型で行う必要があることに注意してくださいイベントを宣言し、サブクラスではありません)、名前と何らかの相関関係を特定できるかどうかを確認しますが、これはせいぜい信頼性の低いソリューションになります。
他のヒント
MulticastDelegate.GetInvocationList()