【问题标题】:How to find which objects are listening to my event?如何找到哪些对象正在监听我的事件?
【发布时间】:2010-12-10 23:28:15
【问题描述】:

我有一堂有活动的课:

public event MyEventHandler MyEvent;

是否有任何方法可以获取正在侦听此事件的对象集合的句柄(通过反射或其他方式)?

编辑 - 嗯,很抱歉移动球门柱 - 我需要能够使用反射来做到这一点,因为我有一个代表事件名称的字符串值,我需要找到听众。我看不到使用反射访问 GetInvocationList 属性的明显方法...

谢谢!

【问题讨论】:

标签: c# events listener


【解决方案1】:
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);

换句话说,事件总是具有属性最近才收到的声明性简写。因此,为了获得调用列表,您必须检查由编译器命名的私有变量(当然,除非您自己使用普通语法并且知道实例变量的名称)。

没有直接的方法可以将外部暴露的event 构造与支持处理程序相关联,就像没有直接的方法将property 绑定到支持变量一样:即因为不一定一对一的关系。很可能有,但通常不必是这样。

您可以尝试使用反射来检查在声明事件的类型上属于正确 EventHandler&lt;&gt; 类型的私有变量(请注意,您必须在 特定类型上进行声明事件,不是在子类上),看看你是否可以确定与名称的某种相关性,但这充其量是一个不可靠的解决方案。

【讨论】:

  • +!好的答案 - 请根据我更新的问题添加如何使用反射来做到这一点?
  • 注意:GetInvocationList() 只能从定义事件的类中调用。
  • @Steve:如果您指的是直接使用事件名称,那么您是正确的。这与我描述的问题相同,其中事件名称在声明类中使用时充当编译器生成的支持委托的“别名”。
【解决方案2】:
MulticastDelegate.GetInvocationList()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-22
    • 2013-09-05
    相关资源
    最近更新 更多