我如何可以检索事件的所有方法?事件、方法

2023-09-04 23:19:06 作者:老朋友

我有一个事件加载

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

我订阅它的方法:

I subscribe to it with a method:

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

是否有可能恢复使用反射这种方法吗?怎么样?

Is it possible to retrieve this method using reflection? How?

推荐答案

在这种特殊情况下的你可以与反思。然而,在一般情况下,你不能。活动封装用户订阅和退订的想法 - 而这一切。订户并不是要找出什么其他的用户也有。

In this particular case you could, with reflection. However, in general, you can't. Events encapsulate the idea of subscribers subscribing and unsubscribing - and that's all. A subscriber isn't meant to find out what other subscribers there are.

一个的现场般的事件的就像刚才显示的是简单地由有关委托类型的字段的支持,与自动生成的添加/删除刚刚使用字段处理程序。然而,没有什么可以说,他们的有无的那样实现。例如,事件可以存储其用户在EventHandlerList,这是有效的,如果你有一个类的几个事件,只有少数人有可能被认购。

A field-like event as you've just shown is simply backed by a field of the relevant delegate type, with autogenerated add/remove handlers which just use the field. However, there's nothing to say they have to be implemented like that. For example, an event can store its subscribers in an EventHandlerList, which is efficient if you have several events in a class and only a few of them are likely to be subscribed to.

现在我想你的可以的试图找到添加处理的机身,反编译,并制定出如何将事件处理程序被存储,并获取他们的方式......但请别。你创造了大量的工作,只是为了打破封装。只要重新设计你的code,这样你就不必这样做。

Now I suppose you could try to find the body of the "add" handler, decompile it and work out how the event handlers are being stored, and fetch them that way... but please don't. You're creating a lot of work, just to break encapsulation. Just redesign your code so that you don't need to do this.

编辑:我已经假设你正在谈论从的获取用户之外的类声明事件。如果你的在的类声明的情况下,那么它很容易,因为你知道如何在事件被存储。

I've been assuming that you're talking about getting the subscribers from outside the class declaring the event. If you're inside the class declaring the event, then it's easy, because you know how the event is being stored.

在这一点上,问题就从获取事件的用户到取组成一个多播委托的个人代表 - 这很容易。正如其他人所说,你可以叫Delegate.GetInvocationList得到与会代表的数组...然后使用Delegate.Method属性来获取方法的特定委托的目标。

At that point, the problem goes from "fetching the subscribers of an event" to "fetching the individual delegates making up a multicast delegate" - and that's easy. As others have said, you can call Delegate.GetInvocationList to get an array of delegates... and then use the Delegate.Method property to get the method that that particular delegate targets.

现在,让我们再来看看你的订阅code:

Now, let's look again at your subscription code:

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

这是我们用来在这里创建委托的方法不是开始 ...这是由C#编译器创建的方法。这将有一个难以启齿的名字(通常是用尖括号),所以看起来是这样的:

The method that's used to create the delegate here isn't Go... it's a method created by the C# compiler. It will have an "unspeakable name" (usually with angle brackets) so will look something like this:

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

现在,是真正要检索什么?或者是你真的希望找出哪些方法的执行的认购,而不是使用哪种方式的作为认购处理器的?

Now, is that actually what you want to retrieve? Or were you really looking to find out which method performed the subscription, rather than which method was used as the subscribed handler?