Raise an event through reflection in C #

I want to write a reuse function to raise an event through reflection.

After searching, I found this similar question: How do I create an event through reflection in .NET / C #?

It works until I register an event handler in the WinForm control and try to call it. The private field ' <EventName> ' just disappears.

Below is my simplified code that reproduces the problem:

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 !!!!!!!!!!!"); } 

Here is my ReflectionHelper class:

 public static class ReflectionHelper { /// <summary> /// Gets method that will be invoked the event is raised. /// </summary> /// <param name="obj">Object that contains the event.</param> /// <param name="eventName">Event Name.</param> /// <returns></returns> 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; } } 

Additional Information:

  • An event in the same class: worked.
  • An event in another class, a subclass in the same assembly: it works.
  • An event in MY differs from build, debug, and release mode: it works.
  • Event in WinForm, DevExpress, ...: does not work

Any help is appreciated.

+6
reflection c # events
source share
2 answers

Events in WinForms are usually overridden and do not have one-on-one delegate support. Instead, the class (basically) has an event-> delegate mapping dictionary, and delegates are only created when events are added. Thus, you cannot assume that the delegate supports the event after you access the reflection field.

Edit: this is the victim of the same problem, but better than getting it as a field and pouring it.

  var eventInfo = currentType.GetEvent(eventName); var eventRaiseMethod = eventInfo.GetRaiseMethod() eventRaiseMethod.Invoke() 
+1
source share

Here is the code I had. "obj" is the object for which you want to call the method, and "methodName" is the method you want to call:

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

Usage example:

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

I did not test this in assemblies, but the project from which I took it was tested, and it worked perfectly.

0
source share

All Articles