lundi 11 janvier 2021

C# reflection: How to subscribe to a event without knowing delegate signature?

I'd like to construct a little adapter class with which a run-time interpreter may intercept the occurance of events regardless of delegate type.

I've tried something like this (which fails with a runtime-exception in the constructor):

public class ModelEvent
{
    private object source;
    private EventInfo sourceEvent;
    private Delegate eventHandler;
    public event EventHandler OnEvent;

    public ModelEvent(object source, EventInfo sourceEvent)
    {
        this.source = source;
        this.sourceEvent = sourceEvent;

        // this line is responsible for the error,
        // the signatures of the eventHandler and delegate method don't match
        this.eventHandler = Delegate.CreateDelegate(
            this.sourceEvent.EventHandlerType,
            this,
            typeof(ModelEvent).GetMethod("OnSourceEvent"));
        // Alternative failed attempts
        // this.eventHandler = new Action<object, object> (this.OnSourceEvent);
        // this.eventHandler = Delegate.CreateDelegate(typeof(EventHandler), this, typeof(ModelEvent).GetMethod("OnSourceEvent"));

        this.sourceEvent.AddEventHandler(this.source, this.eventHandler);
    }

    private void OnSourceEvent(object sender, object eventArgs)
    {
        this.OnEvent?.Invoke(this, EventArgs.Empty);
    }

    // ... truncated for clarity
}

This crashes at runtime, since the (object, object) signature of my OnSourceEvent method does not match any (object, T) signature of the generic EventHandler<T> delegate of the given event sourceEvent.

So I guess I need to construct some sort of wrapper with the correct signature at runtime?

I'm quite new at generics in C# and would appreciate any help in finding a way to construct a viable Delegate, if my interpretation is correct. Thanks a lot!





Aucun commentaire:

Enregistrer un commentaire