c# 反射调用事件

这里有个例子 。这个例子反射调用的是静态的Action。这里最后写了三点需要注意的,我觉得很对。“委托其实是个字段,要用GetField来获取”。
这里的第一个答案。stackoverflow里的,这个就是反射调用事件。

主要差别在反射的筛选条件
typeof(MyClass).GetFields(BindingFlags.NonPublic | BindingFlags.Instance)

对于事件:public event EventHandler<MyEventArgs> Event1;
要用(BindingFlags.NonPublic | BindingFlags.Instance)筛选,
而用(BindingFlags.Public | BindingFlags.Instance)找不到。
(当然,用GetEvent()可以,但是对于EventInfo,我没找到怎么调用它。)

我的代码:

public class MyClass
    {
        public event EventHandler<MyEventArgs> Event1;

        List<FieldInfo> listOfEvent = new List<FieldInfo>();

        public void Test()
        {
            Event1 += F1;

            //下面这句能找到Event1,但是不好进一步调用
            //EventInfo[] eis = typeof(DelageteClass).GetEvents();

            //这样找出来的是私有字段,没想到Event1就在里面。listOfEvent 也在里面
            FieldInfo[] fis = typeof(MyClass).GetFields(BindingFlags.NonPublic | BindingFlags.Instance);

            foreach (var fi in fis)//遍历过滤一下。如果你的类很多私有字段,这个循环的效率方面自己考虑
            {
                var fiType = fi.FieldType;
                var tempType = typeof(EventHandler<MyEventArgs>);
                bool b = fiType == tempType;//根据类型过滤
                if (b)
                {
                    listOfEvent.Add(fi);
                }
            }

            MyEventArgs myEventArgs = new MyEventArgs() { Name = "123" };
            
			//遍历调用。考虑有多个事件。如果只有一个,上面直接根据名字找到,调用一个即可
            foreach (var fi in listOfEvent)
            {
            	//注意:如果事件 Event1 没有挂载事件处理(我这里在上面有: Event1 += F1;),tempV会为null,请自行处理
                var tempV = fi.GetValue(this);//这个很重要,取字段的对象。用GetEvents得到的EventInfo找不到办法获取其对象
                var invokeMethod = tempV.GetType().GetMethod("Invoke");
                try
                {
                    //调用,需要传对象下去。一开始我随便传了个this,抛异常“对象与目标类型不匹配”。至于那个null则无所谓
                    //invokeMethod.Invoke(this, new object[] { null, myEventArgs });
                    invokeMethod.Invoke(tempV, new object[] { null, myEventArgs });
                }
                catch (Exception ex)
                {
                }
            }
        }

        private void F1(object sender, MyEventArgs str)
        {
            Console.WriteLine(str.Name);
        }
    }
    
public class MyEventArgs : EventArgs
    {
        public string Name { get; set; }
    }
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值