public class a
{
public event eventhandler test;
public void RaiseTest(){//fire test}
}
是否可以在此类之外对此类进行测试,而无需调用方法?
基本上我有很多事件必须根据外部源引发,并且不想为每个事件创建一个Raise()函数。
是否可以创建一个通用的Raise()来接受要作为参数引发的事件?因此它仍然会从课堂内召唤?
答案 0 :(得分:5)
你可以通过Reflection来做到这一点,但它不是那么明显。如果在C#中声明一个事件,则会将一个字段添加到具有事件名称+“Event”的类中。如果在字段上调用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将不再是一个问题。
答案 1 :(得分:1)
是否可以在此类之外对此类进行测试,而无需调用方法?
简答:不。
只有声明该事件的类才能引发它
是否可以创建一个通用的Raise()来接受要作为参数引发的事件?因此它仍然会从课堂内召唤?
我不这么认为,至少不容易......即使使用反射,也没有EventInfo.Invoke
方法。 AFAIK,提升事件的唯一方法是在课堂内静态提升
编辑:实际上它可以完成(参见里德的答案),但有限制,即应用必须完全信任。