通过c#中的reflection提升事件

我想编写一个可重用的函数来通过reflection来引发事件。

搜索之后,我发现了类似的问题: 如何通过.NET / C#中的reflection来引发事件?

它一直有效,直到我向WinForm控件注册一个事件处理程序并尝试调用它。 私有字段’ ‘只是消失了。

下面是我的简化代码,它可以重现问题:

Program.cs中:

 public static void Main() { Control control = new Control(); control.Click += new EventHandler(control_Click); MethodInfo eventInvoker = ReflectionHelper.GetEventInvoker(control, "Click"); eventInvoker.Invoke(control, new object[] {null, null}); } static void control_Click(object sender, EventArgs e) { Console.WriteLine("Clicked !!!!!!!!!!!"); } 

这是我的ReflectionHelper类:

 public static class ReflectionHelper { ///  /// Gets method that will be invoked the event is raised. ///  /// Object that contains the event. /// Event Name. ///  public static MethodInfo GetEventInvoker(object obj, string eventName) { // --- Begin parameters checking code ----------------------------- Debug.Assert(obj != null); Debug.Assert(!string.IsNullOrEmpty(eventName)); // --- End parameters checking code ------------------------------- // prepare current processing type Type currentType = obj.GetType(); // try to get special event decleration while (true) { FieldInfo fieldInfo = currentType.GetField(eventName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.GetField); if (fieldInfo == null) { if (currentType.BaseType != null) { // move deeper currentType = currentType.BaseType; continue; } Debug.Fail(string.Format("Not found event named {0} in object type {1}", eventName, obj)); return null; } // found return ((MulticastDelegate)fieldInfo.GetValue(obj)).Method; } } 

附加信息:

  • 在同一课堂上的活动:工作。
  • 不同类中的事件,同一组件中的子类:工作。
  • 不同的汇编,调试和发布模式中的事件:工作。
  • WinForm,DevExpress中的事件……:没有用

任何帮助表示赞赏。

WinForms中的事件通常被覆盖,并且没有一对一的委托支持。 相反,类(基本上)具有事件 – >委托映射的字典,并且仅在添加事件时创建委托。 因此,一旦您使用reflection访问该字段,您就无法假设有一个代表支持该事件。

编辑:这会成为同样问题的牺牲品,但比将其作为一个字段并将其投射更好。

  var eventInfo = currentType.GetEvent(eventName); var eventRaiseMethod = eventInfo.GetRaiseMethod() eventRaiseMethod.Invoke() 

这是我已经存在的一些代码。 ‘obj’是您要调用方法的对象,’methodName’是您要调用的方法:

 public void Invoke(Object obj, String methodName) { MethodInfo m = obj.GetType().GetMethod(methodName); if (m != null) { m.Invoke(obj, null); } } 

用法示例:

 String s = " test string "; Invoke(s, "Trim"); 

我没有在程序集中对此进行测试,但我从中获取的项目已经过测试,效果很好。