如何使用reflection将事件处理程序附加到事件?

我知道EventInfo.AddEventHandler(...)方法,它可以用来将处理程序附加到事件。 但是,如果我甚至无法定义事件处理程序的正确签名,应该怎么做,因为我甚至没有引用处理程序所期望的事件args?

我将用正确的代码解释问题。

//当我在我的解决方案中提供一切可用的场景时,Zero Reflection Scenario。

 internal class SendCommentsManager { public void Customize(IRFQWindowManager rfqWindowManager) { rfqWindowManager.SendComment += HandleRfqSendComment; } private void HandleRfqSendComment(object sender, SendCommentEventArgs args) { args.Cancel = true; } } 

现在,我希望通过使用reflection来实现相同的目标。 我已经能够弄清楚它的大部分但是当我将一个委托附加到事件时(使用AddEventHandler )它会抛出"Error binding to target method." 例外。

我理解这个exception背后的原因,将错误的委托附加到事件中。 但必须有一些方法来实现这一目标。

  internal class SendCommentsManagerUsingReflection { public void Customize(IRFQWindowManager rfqWindowManager) { EventInfo eventInfo = rfqWindowManager.GetType().GetEvent("SendComment"); eventInfo.AddEventHandler(rfqWindowManager, Delegate.CreateDelegate(eventInfo.EventHandlerType, this, "HandleRfqSendComment")); //<<<<<<<<<>>>>>>>>>>>>> } private void HandleRfqSendComment(object sender, object args) { Type sendCommentArgsType = args.GetType(); PropertyInfo cancelProperty = sendCommentArgsType.GetProperty("Cancel"); cancelProperty.SetValue(args, true, null); } } 

我认为你的代码失败了,因为HandleRfqSendComment是私有的。 相反,您可以直接创建该方法的委托,而不将其名称传递给CreateDelegate 。 然后,您需要使用以下方法将委托转换为所需的类型:

 public static Delegate ConvertDelegate(Delegate originalDelegate, Type targetDelegateType) { return Delegate.CreateDelegate( targetDelegateType, originalDelegate.Target, originalDelegate.Method); } 

在您的代码中,您可以使用此方法,如下所示:

 EventInfo eventInfo = rfqWindowManager.GetType().GetEvent("SendComment"); Action handler = HandleRfqSendComment; Delegate convertedHandler = ConvertDelegate(handler, eventInfo.EventHandlerType); eventInfo.AddEventHandler(rfqWindowManager, convertedHandler); 

您可能需要考虑观察者模式: http : //www.dofactory.com/Patterns/PatternObserver.aspx