当前位置:编程学习 > C#/ASP.NET >>

向诸位请教问题,关于反射,委托,事件挂钩的

DLL 1源码:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;


namespace ClassLibrary1
{
   
    public class Class1
    {

      public void start()
        {
            Threadstart = true;
            _sss = new Thread(new ThreadStart(_ss));
            _sss.Start();
        }
        private void _ss()
        {
            int a=0;
            while (Threadstart)//循环
            {
                try
                {
                    a += 1;
                    sMessages(a.ToString());
    
                }
                catch (Exception ex)
                {

                  sMessages(ex.ToString());
                }
                Thread.Sleep(1000);
            }
        }
        [SerializableAttribute]
        [ComVisibleAttribute(true)]
        public delegate void EventHandler(string Messag);
        public event EventHandler sMessages;
    }
}



DLL 2源码:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;


namespace ClassLibrary2
{
   
    public class Class1
    {

      public void start()
        {
            Threadstart = true;
            _sss = new Thread(new ThreadStart(_ss));
            _sss.Start();
        }
        private void _ss()
        {
            int a=0;
            while (Threadstart)//循环
            {
                try
                {
                    a += 1;
                    sMessages(a.ToString());
    
                }
                catch (Exception ex)
                {

                  sMessages(ex.ToString());
                }
                Thread.Sleep(1000);
            }
        }
        [SerializableAttribute]
        [ComVisibleAttribute(true)]
//EventHandler委托
        public delegate void EventHandler(string Messag);
        public event EventHandler sMessages;
    }
}


FROM源码:

....
private void button1_Click(object sender, EventArgs e)
        {
//要启动俩DLL 里的程序
string dllname1 = Application.StartupPath + "\\ClassLibrary1.dll";
string dllname2 = Application.StartupPath + "\\ClassLibrary2.dll";             Assemblys(dllname1, "ClassLibrary1.Class1");
Assemblys(dllname2, "ClassLibrary2.Class1");
        }

        public void Assemblys(string dllname,string classname)//
        {

        Assembly  ass = Assembly.LoadFile(dllname);
        Type t = ass.GetType(classname);
        object  o = Activator.CreateInstance(t);
        MethodInfo  mi = t.GetMethod("start"); 
         mi.Invoke(o, null); //启动DLL内的程序  测试俩DLL已经正常启动

          //挂钩委托方法
      EventInfo evt = t.GetEvent("sMessages");            
 evt.AddEventHandler(o, new EventHandler(MsMessages)); //这里不能使用 +=  这样也无法挂钩 求高手解答   ??????        
        }
  private void MsMessages(string sd)
        {
            MessageBox.Show("测试" + sd);
      
        }
....


问题:
evt.AddEventHandler(o, new EventHandler(MsMessages)); //这里不能使用 +=  这样也无法挂钩 100分求高手解答   ??????       --------------------编程问答-------------------- 转成实体类型才能慢慢挂呀 --------------------编程问答-------------------- +=是语法糖,只能用来操作那些event关键字定义的事件。 --------------------编程问答--------------------
引用 2 楼 caozhy 的回复:
+=是语法糖,只能用来操作那些event关键字定义的事件。

支持,你也可以多用几个
evt.AddEventHandler 一样的效果
--------------------编程问答-------------------- 因为注册事件的委托类型要求是定义event中指定的那个类型,用ClassLibrary1举例就是
 ClassLibrary1.Class.EventHandler 这个委托类型,
而你在AddEventHandler里用的那个显然不是(不知道那个是哪里来的),而MsMessages即使这个方法的签名和委托所定义的签名是一致的,他们也是不相同的两个东西,无法进行转换和替代。
所以你同样要用反射方法类取得原来的委托类型定义并创建委托方法:

//挂钩委托方法
EventInfo evt = t.GetEvent("sMessages");
var delegateType = t.GetNestedTypes().First(x => x.BaseType == typeof(MulticastDelegate) && x.Name == "EventHandler");
evt.AddEventHandler(o, Delegate.CreateDelegate(delegateType, this, "MsMessages"));

还有你注意在ClassLibrary中触发事件的地方要检查是否为空:
if (sMessages != null)
sMessages(a.ToString());
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,