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.