C#:创建一个事件,只要有另一个具有侦听器的事件被触发,就可以通过反射动态地触发它?

时间:2010-09-10 16:06:48

标签: c# events reflection capture subscribe

以下是我正在使用的内容:

我的项目的一部分是一个Windows窗体应用程序。我想基本上捕获每个触发并有听众的事件。所以一些按钮的点击事件,一些复选框的检查事件,基本“控制”事件列表中的所有内容。所以这个事件仍然会发生,但也会引发我的事件。

在我可以使用的引擎盖下是否存在通用的“某事件触发”事件,或者是否有一种方法使用反射来枚举表单中的所有对象,解析所有事件,解析哪些有侦听器,然后除了他们已经去过的地方之外,还要将他们全部订阅到其他地方的通用事件?

任何人都知道怎么做?

2 个答案:

答案 0 :(得分:4)

你根本不能这样做:一个事件是一个黑盒子,只有“订阅”和“取消订阅”功能。因此,虽然您可以使用反射来查找所有事件,但您无法可靠地检测已订阅的事件。对于类似字段的事件,您可以获取支持字段并检查它是否为空,但即使这样也不可靠 - 为了避免空检查,作者可能写了类似这样的事情:

public event EventHandler SomeEvent = delegate {};

对于其他事件,您必须确定订阅该事件的实际操作 - 例如,它可能使用EventHandlerList

基本上,您应该重新考虑您的设计,这样您就不需要这样做了。

答案 1 :(得分:0)

订阅事件被触发的事实是否表明它有订阅者?那么您需要的只是一个可订阅事件列表,您可以在intercepted call期间对其进行验证。

您可以使用任何AOP框架拦截来电。例如,通过使用Unity Interception,您可以执行以下操作:

public IMethodReturn Invoke(IMethodInvocation input, 
    GetNextHandlerDelegate getNext)
{
    // 1. assuming that you are keeping a list of method names 
    // that are being subscribed to.
    // 2. assuming that if the event is fired, then it must have
    // been subscribed to... 
    if (MyReflectedListOfSubscribedEvents.Contains(input.MethodBase.ToString())
    {
        HandleItSomeHow();
    }

    // process the call...
    return getNext().Invoke(input, getNext);
}