簡體   English   中英

嘗試使用反射為 dll 操作添加事件處理程序時,“類型為‘System.EventHandler’的對象無法轉換為類型‘System.Action’”

[英]"Object of type 'System.EventHandler' cannot be converted to type 'System.Action'" when trying to add event handler for dll action using reflection

我有以下兩個程序

Windows窗體應用程序

類庫1 dll

ClassLibrary1 dll 通過 appdomain 加載加載到 Windowsform。 我已經通過應用程序域的反射訂閱了 dll 事件。 我正在嘗試訂閱 dll 操作 (TestAction) 並處理 windows forms 中的操作。但是我收到此錯誤“類型為‘System.EventHandler’的對象無法轉換為類型‘System.Action’”

這是 windows 表單代碼:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.Diagnostics;
using ClassLibrary1;

namespace WindowsFormsApplication2
{
    [Serializable]
    public partial class Form1 : Form
    {
        void HandleEvent(object sender, EventArgs e)
        {
            Debug.WriteLine("HandleEvent called");
        }
        void HandleAction(object sender, EventArgs e)
        {
            Debug.WriteLine("HandleAction called");
        }
        public Form1()
        {
            InitializeComponent();
            Loader.Call(  "RaiseEvent", HandleEvent, DateTime.Now.ToShortDateString());
            Loader.Call( "RaiseAct", HandleAction, DateTime.Now.ToShortDateString());
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Application.Restart();
            Application.Run(new Form1());
            this.Close();
        }
    }

    public class Loader : MarshalByRefObject
    {
        static string dll = @"..\ConsoleApplication1\ClassLibrary1\bin\Debug\ClassLibrary1.dll";
        static AppDomain ad = AppDomain.CreateDomain("Test");
        static Assembly a = Assembly.LoadFile(dll);
        static object o = a.CreateInstance("ClassLibrary1.Class1");
        static Type t = o.GetType();

        object CallInternal1( string method, EventHandler handler, object[] parameters)
        {
            // Subscribe to the event
            EventInfo eventInfo1 = t.GetEvent("TestEvent");
            eventInfo1.AddEventHandler(o, handler);

            MethodInfo m = t.GetMethod(method);
            return m.Invoke(o, parameters);
        }

        object CallInternal2( string method, EventHandler handler, object[] parameters)
        {
            // Subscribe to the event
            EventInfo eventInfo2 = t.GetEvent("TestAction");
            eventInfo2.AddEventHandler(o, handler);               // Error: Object of type 'System.EventHandler' cannot be converted to type 'System.Action

            MethodInfo m = t.GetMethod(method);
            return m.Invoke(o, parameters);
        }

        public static object Call( string method, EventHandler handler, params object[] parameters)
        {
            Loader ld = (Loader)ad.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(Loader).FullName);
            object result = 0;
            switch (method)
            {
                case "RaiseEvent":
                    {
                        result = ld.CallInternal1( method, handler, parameters);
                        break;
                    }

                case "RaiseAct":
                    {
                        result = ld.CallInternal2( method, handler, parameters);
                        break;
                    }
            }
            return result;
        }
    }
}

這是ClassLibrary1.dll代碼

 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ClassLibrary1 { [Serializable] public class Class1 { public event EventHandler TestEvent; public int RaiseEvent(string msg) { try { TestEvent(this, EventArgs.Empty); } catch (Exception ex) { Console.WriteLine("the exception is: " + ex.ToString()); if (ex.InnerException.= null) { Console:WriteLine("the inner exception is. " + ex.InnerException.Message;ToString()); } } return 2; } public event Action<int> TestAction = Func; public int RaiseAct(string msg) { TestAction(3); return 5; } public static void Func(int a) { int g = 2; } } }

事件的類型是Action ,因此您可以將處理程序封裝在Action中。

eventInfo2.AddEventHandler(o, new Action(() => handler(null, EventArgs.Empty)));

更新評論中的問題,您可以定義EventArgs的子 class 並將其傳遞給事件處理程序。

class IntEventArgs : EventArgs { public int data; }
new Action<int>((index) => handler(null, new IntEventArgs{ data = index }))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM