Q:

Add and remove event handler via reflection c#

Good day!
My purpose is to implement class which will allow us subscribe and unsubscribe objects to(from) events. Here is the code of my class.
public static class EventSubscriber
{
    public static void AddEventHandler(EventInfo eventInfo, object item, Action action)
    {
        var parameters = GetParameters(eventInfo);
        var handler = GetHandler(eventInfo, action, parameters);
        eventInfo.AddEventHandler(item, handler);
    }

    public static void RemoveEventHandler(EventInfo eventInfo,
                        object item, Action action)
    {
        var parameters = GetParameters(eventInfo);
        var handler = GetHandler(eventInfo, action, parameters);
        eventInfo.RemoveEventHandler(item, handler);
    }

    private static ParameterExpression[] GetParameters(EventInfo eventInfo)
    {
        return eventInfo.EventHandlerType
          .GetMethod("Invoke")
          .GetParameters()
          .Select(parameter => Expression.Parameter(parameter.ParameterType))
          .ToArray();
    }

    private static Delegate GetHandler(EventInfo eventInfo,
                Action action, ParameterExpression[] parameters)
    {
        return Expression.Lambda(
            eventInfo.EventHandlerType,
            Expression.Call(Expression.Constant(action),
                      "Invoke", Type.EmptyTypes), parameters)
          .Compile();
    }
}

As you can see here are 2 public methods which actually subscribe and unsubscribe objects to(from) event. And here is the sample how I test it
class Program
{
    static void Main()
    {
        Test test = new Test();
        test.SubscribeTimer();
        while (true)
        {
            if(test.a == 10)
            {
                break;
            }
        }
        test.UnsubscribeTimer();
        while (true)
        {

        }
    }
}

class Test
{
    System.Timers.Timer timer;
    public int a = 0;

    public Test()
    {
        timer = new System.Timers.Timer(1000);
        timer.Start();
    }

    public void SubscribeTimer()
    {
        var eventInfo = typeof(System.Timers.Timer).GetEvent("Elapsed");
        EventSubscriber.AddEventHandler(eventInfo, timer, TimerElapsed);
        EventSubscriber.RemoveEventHandler(eventInfo, timer, TimerNotElapsed);
    }

    public void UnsubscribeTimer()
    {
        var eventInfo = typeof(System.Timers.Timer).GetEvent("Elapsed");
        EventSubscriber.AddEventHandler(eventInfo, timer, TimerNotElapsed);
        EventSubscriber.RemoveEventHandler(eventInfo, timer, TimerElapsed);
    }

    public void TimerElapsed()
    {
        Console.WriteLine("timer elapsed");
        a++;
    }

    public void TimerNotElapsed()
    {
        Console.WriteLine("timer not elapsed");
        a++;
    }
}

The expected behaviour of sample is that on the begining we will see the message "timer elapsed" every second, after 10-th second we should see only "timer not elapsed" and we do, but we still see "timer elapsed" too. This means that AddEventHandler method works, but RemoveEventHandler method doesn't.
I would be very happy if you will help me. Thanks in advance.

A:

I think it's because you are creating a new handler each time: (which doesn't match the previous handler, so can't be removed from the invocation list)
public static void RemoveEventHandler(EventInfo eventInfo,
                    object item, Action action)
{
    var parameters = GetParameters(eventInfo);
    var handler = GetHandler(eventInfo, action, parameters); // <--
    eventInfo.RemoveEventHandler(item, handler);
}

Why are you wrapping the Action? To lose the parameters? It is not possible to add/remove the eventInfo.RemoveEventHandler(item, action); because of the parameters. If you want to remove a newly generated handler, you should return that handler when you want to remove it.
public static Delegate AddEventHandler(EventInfo eventInfo, object item, Action action)
{
    var parameters = GetParameters(eventInfo);
    var handler = GetHandler(eventInfo, action, parameters);
    eventInfo.AddEventHandler(item, handler);
    return handler;
}

public static void RemoveEventHandler(EventInfo eventInfo,
                    object item, Delegate handler)
{
    eventInfo.RemoveEventHandler(item, handler);
}

var handler = EventSubscriber.AddEventHandler(eventInfo, timer, TimerElapsed);

EventSubscriber.RemoveEventHandler(eventInfo, timer, handler);

