C#创建一个触发事件的委托?

时间:2010-10-29 03:37:07

标签: c# events reflection delegates

是否可以使用Reflection is C#来触发事件?说我有这样的情况:

public delegate void SomeEventHandler(object sender, BenArgs e);

class EventHub
{
    public event SomeEventHandler SOME_EVENT;

    public void fireEvent(String eventName)
    {
        SomeEventHandler evt = (SomeEventHandler) Delegate.CreateDelegate(typeof(SomeEventHandler), this, eventName);

        evt.Invoke(null, null);
    }
}

我打电话的意思

EventHub.fireEvent("SOME_EVENT")

然后它会使事件集线器触发SOME_EVENT?我试过这个,只是出现例外情况。

这主要是我的一个好奇心,我知道在这种情况下,我可以轻松地在没有反射的情况下发射事件。

1 个答案:

答案 0 :(得分:3)

假设您当前的情况,即:

  1. 类似田野的活动。
  2. 支持委托字段与事件名称相同。
  3. (this, EventArgs.Empty)是传递给委托的有效参数。
  4. 您可以执行以下操作(需要更多参数验证):

    public void fireEvent(String eventName)
    {
        // Get a reference to the backing field
        var del = (Delegate)typeof(EventHub)
                    .GetField(eventName, BindingFlags.NonPublic | BindingFlags.Instance)
                    .GetValue(this);
    
         // Invoke the delegate, it's invocation-list will contain the listeners
         if(del != null)
            del.DynamicInvoke(this, EventArgs.Empty);
    }
    

    用法:

      var eHub = new EventHub();
      eHub.SOME_EVENT += delegate { Console.WriteLine("SOME_EVENT fired.."); };      
      eHub.fireEvent("SOME_EVENT");
    

    现在,如果您愿意,可以使用object上的扩展方法来概括这个想法,但所有这些都是一个非常糟糕的主意。在一般情况下,此问题无法解决,因为无法知道事件是如何“实施”的。 addremove方法中可能存在任意代码,“触发”事件的逻辑也可以是任何内容。甚至可能没有用于存储侦听器的支持多播delgate字段。

    在任何情况下,尝试告诉对象发射事件几乎总是一个主要设计缺陷的标志,IMO。如果仍然确实想要这个,那么在你的班级中声明这样的方法会好得多:

    public void RaiseXXXEvent() { ... }