简体   繁体   中英

AddEventHandler using reflection to a static class

I need to append new method to the existing event of a static class. This is my 'cat' static class and cant change it because it it 3rd party. I need to add new method to trigger in the same event myEvent . This question shows how to do it for non static class. But I'm not sure how to do for static class. Someone there to help?

public static class Cat
{
 internal static event EventHandler myEvent;

public static init()
{
....
....
}

}

class Dog
{
 public static void init()
 {
   EventInfo eventInfo = typeof(Cat).GetEvent("myEvent");

      if (eventInfo != null)
      {
       Delegate handler =  Delegate.CreateDelegate(eventInfo.EventHandlerType, , newMethod); // I'm stuck here
       eventInfo.AddEventHandler(, handler);  // I'm stuck here

     }
 }

  static void newMethod()
  {

  }
}

If the myEvent is public I can do Cat.myEvent+= new EventHandler(newMethod); . But unluckily it is internal

You should add a few things. First, add BindingFlags to the GetEvent , since the event is static and non-public. By default GetEvent only returns public instance events:

EventInfo eventInfo = typeof(Cat).GetEvent("myEvent", BindingFlags.Static | BindingFlags.NonPublic);

Second, use another overload of CreateDelegate to make a delegate to a static method, the one with two parameters. Or use yours, with null as the second parameter.

Third, use null as the first parameter of AddEventHandler . Normally you pass the instance as the first parameter, but since this event is static, it does not need an instance:

eventInfo.AddEventHandler(null, handler);  

You didn't get very far, but you are going to hit the wall pretty hard when you'll try to use AddEventHandler(). The CLR enforces the accessibility of the event even when you try to hack it with reflection. And since it is not public , reflection isn't going to help.

You'll have to reach for a bigger weapon. Assuming the event is not custom and the moon is in the right quadrant, the C# compiler generates an add accessor method. It is a method named add_myEvent() . Do use a decompiler to verify the name, surely it isn't actually named that way.

First thing you have to do is give your event handler the correct signature, one that matches the delegate type:

    static void newMethod(object sender, EventArgs e) {
        // etc..
    }

Then you can write the reflection code like this:

    public static void init() {
        EventInfo eventInfo = typeof(Cat).GetEvent("myEvent",
            BindingFlags.NonPublic | BindingFlags.Static);
        MethodInfo adder = typeof(Cat).GetMethod("add_myEvent",
            BindingFlags.NonPublic | BindingFlags.Static);
        MethodInfo target = typeof(Dog).GetMethod("newMethod", 
            BindingFlags.NonPublic | BindingFlags.Static);
        Delegate handler =  Delegate.CreateDelegate(eventInfo.EventHandlerType, target);
        adder.Invoke(null, new object[] { handler });
    }

There is no need for Delegate.CreateDelegate since Dog is under your control.

This code works as expected:

namespace ConsoleApplication1
{

    public static class Cat
    {
        internal static event EventHandler myEvent;

        public static void RaiseEvent()
        {
            if (myEvent != null) myEvent(typeof(Cat), EventArgs.Empty);
        }
    }


    class Dog
    {
        public static void init()
        {
            MethodInfo addInfo = typeof(Cat).GetMethod("add_myEvent", BindingFlags.NonPublic | BindingFlags.Static);
            EventHandler handler = new EventHandler(Handler);
            addInfo.Invoke(null, new object[] { handler });
        }

        static void Handler(object sender, EventArgs e)
        {
            Console.WriteLine("Event fired");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Dog.init();
            Cat.RaiseEvent();
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM