c# - 如何使用反射将事件处理程序附加到事件?

标签 c# events reflection event-handling delegates

我知道 EventInfo.AddEventHandler(...) 方法可用于将处理程序附加到事件。但是,如果我什至不能定义事件处理程序的正确签名,应该怎么办,例如,我什至没有引用处理程序期望的事件参数?

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

//当我的解决方案中的所有内容都可用时的场景,零反射场景。

internal class SendCommentsManager
{
    public void Customize(IRFQWindowManager rfqWindowManager)
    {
        rfqWindowManager.SendComment += HandleRfqSendComment;
    }

    private void HandleRfqSendComment(object sender, SendCommentEventArgs args)
    {
        args.Cancel = true;
    }
}

现在,我想通过反射来达到同样的目的。我已经能够弄清楚其中的大部分内容,但是当我将委托(delegate)附加到事件时(使用 AddEventHandler),它会抛出 "Error binding to target method." 异常。

我理解此异常背后的原因,将错误的委托(delegate)附加到事件。但必须有某种方法可以实现这一目标。

 internal class SendCommentsManagerUsingReflection
 {
     public void Customize(IRFQWindowManager rfqWindowManager)
     {
         EventInfo eventInfo = rfqWindowManager.GetType().GetEvent("SendComment");
         eventInfo.AddEventHandler(rfqWindowManager, 
             Delegate.CreateDelegate(eventInfo.EventHandlerType, this, "HandleRfqSendComment"));
         //<<<<<<<<<<ABOVE LINE IS WHERE I AM GOING WRONG>>>>>>>>>>>>>>
     }

     private void HandleRfqSendComment(object sender, object args)
     {
         Type sendCommentArgsType = args.GetType();
         PropertyInfo cancelProperty = sendCommentArgsType.GetProperty("Cancel");
         cancelProperty.SetValue(args, true, null);
     }
 }

最佳答案

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

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

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

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

关于c# - 如何使用反射将事件处理程序附加到事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3120422/

相关文章:

c# - 反射调用方法 - 参数异常

c# - 为什么 ContextMenuOpening 的 Source 对 Canvas 和 UserControl 的行为不同?

搜索事件的 Jquery 选择器

java - 动态地将Object实例转换为真正的子类实例

c# - 带有AllowsTransparency = true的ResizeMode.CanResize不起作用

c# - 以异步方式启动任务的其他方式

c# - 如何在Windows窗体应用程序c#中自动显示更新的版本号?

javascript - 获取Li点击索引号

java - 如何使用反射自动注册spring bean

c# - 为属性创建委托(delegate)时无法绑定(bind)到目标方法