【问题标题】:AddEventHandler using reflectionAddEventHandler 使用反射
【发布时间】:2010-11-10 10:09:17
【问题描述】:

我有这段代码不起作用:

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);
}

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

【问题讨论】:

    标签: c# .net events reflection


    【解决方案1】:

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

    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());
            }
        }
    }
    

    【讨论】:

    • 我对代码的唯一担心是Func&lt;&gt; 委托不太适合事件。如果您有多个事件订阅,则只有其中一个会实际产生返回值,这可能会导致应用程序的不确定行为。
    【解决方案2】:

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

    想法:

    • 事件和处理程序都是公开的吗?如果没有,您需要将合适的 BindingFlags 传递给 GetEvent / GetMethod 调用。
    • 处理程序的签名是否匹配?

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

    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");
        }
    }
    

    【讨论】:

    • 我什么也没看到。什么都没发生。
    【解决方案3】:

    这是一个简短但完整的示例,确实工作:

    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();
        }
    }
    

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

    您能提供更多信息吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-18
      • 2017-10-30
      • 1970-01-01
      • 2017-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-05
      相关资源
      最近更新 更多