will you listen to an event and invoke callbacks based on specification?

Problem with (proposed) approach like this:

TryRegisterAndStartTask(task, out Guid taskId, task.OnSomething, OnSomethingWasRaised);

is that you cannot pass event as argument, or store it in variable, because event is just a set of two methods (add and remove), just like property is a set of two methods get and set.

You can of course change event to “raw” delegate:

public EventHandler<EventArgs> OnSomething;

This one you can pass by reference:

public bool TryRegisterAndStartTask(CustomTask task, ref EventHandler<EventArgs> del, EventHandler<EventArgs> sub, out Guid taskId) {
        taskId = Guid.Empty;
        // subscribe
        del += sub;
        ...
} 

CustomTaskManager.Instance.TryRegisterAndStartTask(task, ref task.OnSomething, OnSomethingWasRaised, out var taskId);

But that’s usually not a good idea, since you are losing private scope of events – with events one can only add\remove delegates, with raw delegate anyone can do anything, like invoking or setting to null.

If regular event stays – that means reflection is the only way to achieve your goal, and even worse – you’ll have to reference to the event you want to subscribe to by string name, not by an actual reference, though you can use nameof(task.OnSomething). Then, you are losing compile time validation of subscription delegate type. Say you want to subscribe to event Action Something but passing Func<string> delegate there. It will compile fine with reflection approach, and fail only at runtime.

Still if you insist that will look something like this:

public bool TryRegisterAndStartTask(CustomTask task, string eventName, Delegate sub, out Guid taskId) {
    taskId = Guid.Empty;
    // subscribe
    var ev = task.GetType().GetEvent(eventName, BindingFlags.Public | BindingFlags.Instance);
    var addMethod = ev.GetAddMethod(); // this can be null or private by the way
    addMethod.Invoke(task, new [] {sub});
    ...
}

And called like this:

var task = new CustomTaskA();
EventHandler<EventArgs> handler = OnSomethingWasRaised;
CustomTaskManager.Instance.TryRegisterAndStartTask(task, nameof(task.OnSomething), handler, out var taskId);

Ugly, unsafe, and not worth it in your scenario, in my opinion.

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top