I need to copy the subscribers of one event to another event. Can I get the subscribers of an event (like MyEvent[0] returning a delegate)?
If this is not possible I would use the add accessor to add the delegates to a list. Would that be the best solution?
The publisher determines when an event is raised; the subscribers determine what action is taken in response to the event. An event can have multiple subscribers. A subscriber can handle multiple events from multiple publishers. Events that have no subscribers are never raised.
To subscribe to events programmatically Use the addition assignment operator ( += ) to attach an event handler to the event.
An event subscriber is a C/AL function that subscribes to, or listens for, a specific event that is declared by an event publisher function. The event subscriber includes code that defines the business logic to handle the event. When the published event is raised, the event subscriber is called and its code is run.
An event subscription is a registration indicating that a particular event is significant to a particular system and specifying the processing to perform when the triggering event occurs. You can define your event subscriptions in the Event Manager.
C# events/delegates are multicast, so the delegate is itself a list. From within the class, to get individual callers, you can use:
if (field != null) { // or the event-name for field-like events // or your own event-type in place of EventHandler foreach(EventHandler subscriber in field.GetInvocationList()) { // etc } }
However, to assign all at once, just use += or direct assignment:
SomeType other = ... other.SomeEvent += localEvent;
If the event is one published by another class, you can't - at least, not reliably. While we often think of an event as being just a delegate variable, it's actually just a pair of methods: add and remove (or subscribe and unsubscribe).
If it's your own code that's publishing the event, it's easy - you can make the add/remove accessors do whatever you like.
Have a look at my article on events and see if that helps you. If not, please give more details about what you want to do, specifying which bits of code you're able to modify and which you aren't.
In case you need to examine subscribers of an external class' event:
EventHandler e = typeof(ExternalClass)
.GetField(nameof(ExternalClass.Event), BindingFlags.Instance | BindingFlags.NonPublic)
.GetValue(instanceOfExternalClass) as EventHandler;
if (e != null)
{
Delegate[] subscribers = e.GetInvocationList();
}
Update (thanks to commenters): delegate immutability means that cloning achieves nothing over an assignment.
When one writes:
myDelegate += AHandler
A completely new delegate instance is created and assigned to myDelegate
.
Therefore, the code below would work exactly the same without the Clone call.
MulticastDelegate
(the underlying type) has a Clone
method.
To be able to get to the underlying delegate you might need to avoid the usual helper that the event keyword generates, and manage things directly (custom add and remove accessors).
To show this:
public class Program {
public delegate void MyDelegate(string name);
public event MyDelegate EventOne;
public void HandlerOne(string name) => Console.WriteLine($"This is handler one: {name}");
public void HandlerTwo(string name) => Console.WriteLine($"This is handler two: {name}");
public void HandlerThree(string name) => Console.WriteLine($"This is handler three: {name}");
public void Run() {
EventOne += HandlerOne;
EventOne += HandlerTwo;
Console.WriteLine("Before clone");
EventOne("EventOne");
MyDelegate eventTwo = (MyDelegate)EventOne.Clone();
MyDelegate eventTwo = EventOne;
Console.WriteLine("After clone copy");
EventOne("EventOne");
eventTwo("eventTwo");
Console.WriteLine("Change event one to show it is different");
EventOne += HandlerThree;
EventOne("EventOne");
eventTwo("eventTwo");
}
private static void Main(string[] args) => (new Program()).Run();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With