public class a
{
public event eventhandler test;
public void RaiseTest(){//fire test}
}
是否可以在不调用该方法的情况下从此类外部对此类进行测试?
基本上我有大量事件必须基于外部源引发,并且不想为每个事件创建一个 Raise() 函数。
是否可以创建一个通用的 Raise() 接受要引发的事件作为参数?因此它仍然会从类内部调用吗?
您可以通过反射来做到这一点,但这并不明显。如果你在 C# 中声明一个事件,一个字段将被添加到类中,事件名称+“事件”。如果您在该字段上调用 GetValue,它将返回一个 MulticastDelegate 实例。
拥有 MulticastDelegate 后,您可以获取调用列表,并依次调用每个成员:
EventArgs e = new EventArgs(myClassInstance); // Create appropriate EventArgs
MulticastDelegate eventDelagate =
this.GetType().GetField(theEventName + "Event",
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.NonPublic).GetValue(myClassInstance) as MulticastDelegate;
Delegate[] delegates = eventDelagate.GetInvocationList();
foreach (Delegate del in delegates) {
del.Method.Invoke(del.Target, new object[] { myClassInstance, e });
}
请注意,这需要从实例中获取 NonPublic 字段,因此它只能在完全信任的情况下工作,并且非常有限。
是否可以创建一个通用的 Raise() 接受要引发的事件作为参数?因此它仍然会从类内部调用吗?
是的。修改上面的代码来做到这一点是相当容易的。只需用这个替换“myClassInstance”。这实际上也将允许它在完全信任的情况下正常工作,因为 NonPublic BindingFlag 将不再是一个问题。
是否可以在不调用该方法的情况下从此类外部对此类进行测试?
简短的回答:不。
只有声明事件的类才能引发它
是否可以创建一个通用的 Raise() 接受要引发的事件作为参数?因此它仍然会从类内部调用吗?
我不这么认为,至少不容易......即使使用反射,也没有EventInfo.Invoke
方法。AFAIK,引发事件的唯一方法是在班级内静态地
编辑:实际上它可以做到(见里德的回答),但限制是应用程序必须完全信任运行。