C# 使用反射的 AddEventHandler

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1121441/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 08:42:19  来源:igfitidea点击:

AddEventHandler using reflection

c#.neteventsreflection

提问by pedrofernandes

I have this piece of code that does not work:

我有这段代码不起作用:

public CartaoCidadao()
{
    InitializeComponent();

    object o = WebDAV.Classes.SCWatcher.LoadAssembly();
    MethodInfo method = 
        this.GetType().GetMethod("Inserted", 
                                 BindingFlags.NonPublic | BindingFlags.Instance);

    EventInfo eventInfo = o.GetType().GetEvent("CardInserted");
    Type type = eventInfo.EventHandlerType;
    Delegate handler = Delegate.CreateDelegate(type, this , method);

    eventInfo.AddEventHandler(o, handler);
}

void Inserted(string readerName, string cardName)
{
    System.Windows.Forms.MessageBox.Show(readerName);
}

The Event CardInserted exists in another DLL file and object "o" loads OK. The delegate handler has a value after effect. I only can't fire the event.

事件 CardInserted 存在于另一个 DLL 文件中,并且对象“o”加载正常。委托处理程序在效果后有一个值。我只是不能触发事件。

采纳答案by Darin Dimitrov

Here's a sample showing how to attach an event using reflection:

这是一个示例,展示了如何使用反射附加事件:

class Program
{
    static void Main(string[] args)
    {
        var p = new Program();
        var eventInfo = p.GetType().GetEvent("TestEvent");
        var methodInfo = p.GetType().GetMethod("TestMethod");
        Delegate handler = 
             Delegate.CreateDelegate(eventInfo.EventHandlerType, 
                                     p, 
                                     methodInfo);
        eventInfo.AddEventHandler(p, handler);

        p.Test();
    }

    public event Func<string> TestEvent;

    public string TestMethod()
    {
        return "Hello World";
    }

    public void Test()
    {
        if (TestEvent != null)
        {
            Console.WriteLine(TestEvent());
        }
    }
}

回答by Marc Gravell

When you say it doesn't work... what happens? Nothing? An exception?

当你说它不起作用时......会发生什么?没有?例外?

Thoughts:

想法:

  • are both the event and the handler public? If not, you'll need to pass suitable BindingFlagsto the GetEvent/ GetMethodcalls.
  • does the signature of the handler match?
  • 事件和处理程序都是公开的吗?如果没有,您需要将合适BindingFlags的传递给GetEvent/GetMethod调用。
  • 处理程序的签名是否匹配?

Here's a working example (note I'm using a static handler, hence the null in Delegate.CreateDelegate):

这是一个工作示例(注意我使用的是静态处理程序,因此在 中为空Delegate.CreateDelegate):

using System;
using System.Reflection;
class Test
{
    public event EventHandler SomeEvent;
    public void OnSomeEvent()
    {
        if (SomeEvent != null) SomeEvent(this, EventArgs.Empty);
    }
    static void Main()
    {
        Test obj = new Test();
        EventInfo evt = obj.GetType().GetEvent("SomeEvent");
        MethodInfo handler = typeof(Test)
            .GetMethod("MyHandler");
        Delegate del = Delegate.CreateDelegate(
            evt.EventHandlerType, null, handler);
        evt.AddEventHandler(obj, del);

        obj.OnSomeEvent();
    }

    public static void MyHandler(object sender, EventArgs args)
    {
        Console.WriteLine("hi");
    }
}

回答by Jon Skeet

Here's a short but complete example which doeswork:

这是一个简短但完整的示例,它确实有效:

using System;
using System.Reflection;

class EventPublisher
{
    public event EventHandler TestEvent;

    public void RaiseEvent()
    {
        TestEvent(this, EventArgs.Empty);
    }
}

class Test
{

    void HandleEvent(object sender, EventArgs e)
    {
        Console.WriteLine("HandleEvent called");
    }

    static void Main()
    {
        // Find the handler method
        Test test = new Test();
        EventPublisher publisher = new EventPublisher();
        MethodInfo method = typeof(Test).GetMethod
            ("HandleEvent", BindingFlags.NonPublic | BindingFlags.Instance);

        // Subscribe to the event
        EventInfo eventInfo = typeof(EventPublisher).GetEvent("TestEvent");
        Type type = eventInfo.EventHandlerType;
        Delegate handler = Delegate.CreateDelegate(type, test, method);

        // Raise the event
        eventInfo.AddEventHandler(publisher, handler);
        publisher.RaiseEvent();
    }
}

Now, when you say "I only can't fire event", what exactly do you mean? You're not meant to be able to raise events yourself - it's up to the event publisher to do that. Does all of the code you've actually presented to us work? If so, it seems that it's not adding the event handler that's the problem.

现在,当您说“我只能触发事件”时,您到底是什么意思?您不能自己发起事件——这取决于事件发布者。您实际提供给我们的所有代码都有效吗?如果是这样,它似乎没有添加问题处理程序。

Could you give more information?

你能提供更多信息吗?