这里有个例子 。这个例子反射调用的是静态的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; }
}