如何检索事件的所有方法?

时间:2010-09-23 19:44:06

标签: c# .net reflection

我有一个活动Load

public delegate void OnLoad(int i);
public event OnLoad Load;

我用方法订阅它:

public void Go()
{
    Load += (x) => { };
}

是否可以使用反射检索此方法?怎么样?

3 个答案:

答案 0 :(得分:8)

这个特例你可以用反射。但是,一般情况下,你不能。事件封装了订阅者订阅和取消订阅的想法 - 这就是全部。订户并不意味着找出其他订户。

您刚才显示的字段式事件只是由相关委托类型的字段支持,自动生成的添加/删除处理程序只使用该字段。但是,没有什么可说的,他们这样实现。例如,一个事件可以将其订阅者存储在EventHandlerList中,如果您在一个类中有多个事件并且只有少数事件可能被订阅,则该事件是有效的。

现在我想你可以尝试找到“add”处理程序的主体,对其进行反编译并找出事件处理程序的存储方式,并以这种方式获取它们......但是请别。你正在创造很多工作,只是为了打破封装。只需重新设计代码,这样就不需要这样做了。

编辑:我一直在假设您正在谈论从外面获取订阅者宣布该事件。如果您在内部声明事件的类,那么这很容易,因为您知道事件是如何存储的。

此时,问题从“获取事件的订阅者”到“获取构成多播委托的各个代表” - 这很容易。正如其他人所说,您可以调用Delegate.GetInvocationList来获取一组委托......然后使用Delegate.Method属性来获取该特定委托所针对的方法。

现在,让我们再看一下您的订阅代码:

public void Go()
{
    Load += (x) => { };
}

此处用于创建委托的方法不是Go ...它是由C#编译器创建的方法。它将有一个“无法形容的名称”(通常带有尖括号),所以看起来像这样:

[CompilerGenerated]
private static void <Go>b__0(int x)
{
}

现在,这实际上是你要检索的吗?或者你真的想找出执行订阅的方法,而不是使用哪种方法作为订阅处理程序

答案 1 :(得分:0)

如果您调用Load.GetInvocationList(),您将返回一组Delegate类型。从这些类型中,您可以访问MethodInfo。

答案 2 :(得分:0)

您可以使用GetInvocationList方法为您提供所有订阅者。