4
public class a
{
   public event eventhandler test;
   public void  RaiseTest(){//fire test}
}

是否可以在不调用该方法的情况下从此类外部对此类进行测试?

基本上我有大量事件必须基于外部源引发,并且不想为每个事件创建一个 Raise() 函数。

是否可以创建一个通用的 Raise() 接受要引发的事件作为参数?因此它仍然会从类内部调用吗?

4

2 回答 2

5

您可以通过反射来做到这一点,但这并不明显。如果你在 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 将不再是一个问题。

于 2009-08-04T22:36:41.717 回答
1

是否可以在不调用该方法的情况下从此类外部对此类进行测试?

简短的回答:不。

只有声明事件的类才能引发它

是否可以创建一个通用的 Raise() 接受要引发的事件作为参数?因此它仍然会从类内部调用吗?

我不这么认为,至少不容易......即使使用反射,也没有EventInfo.Invoke方法。AFAIK,引发事件的唯一方法是在班级内静态地

编辑:实际上它可以做到(见里德的回答),但限制是应用程序必须完全信任运行。

于 2009-08-04T22:30:00.967 回答