I have the following line in C#:
_timer.ElapsedTick += _somefunction1; _timer.ElapsedTick += _somefunction2; _timer.ElapsedTick += _somefunction3;
How to invoke all methods subscribed to _timer.ElapsedTick without specifying the _somefunction ? Somewhere along this pseudo-line
invoke(_timer.ElapsedTick);
You need to first get the field that represents the event on the type as a MulticastDelegate , then get its invocationlist and from there you can dynamically invoke each method individually. The answer to this MSDN question shows how to do it.
If you REALLY need to call an event manually, you can get the backing delegate, which is usually private. Use a . NET decompiler (such as ILSPY) to locate the Event's backing field, then use reflection to get the backing delegate. So you need to find the Events member, and the doWorkKey field as a key.
EventArgs is also the class you use when an event does not have any data associated with it. When you create an event that is only meant to notify other classes that something happened and does not need to pass any data, include the EventArgs class as the second parameter in the delegate. You can pass the EventArgs.
Yes, you can declare an event without declaring a delegate by using Action. Action is in the System namespace.
You can't invoke an event which is owned by another type. An event can only be invoked from the inside the class which declares it.
Can it be done using conventional C#? No (as previously stated). But using reflection it is possible. Here is some tested code based on the answer to this MSDN forum thread:
class InvokeFromMe { public event EventHandler RaiseMe; } class Program { static void Main(string[] args) { var fromMe = new InvokeFromMe(); fromMe.RaiseMe += fromMe_RaiseMe; fromMe.RaiseMe += fromMe_RaiseMe1; fromMe.RaiseMe += fromMe_RaiseMe2; FireEvent(fromMe, "RaiseMe", null, EventArgs.Empty); } static void fromMe_RaiseMe(object sender, EventArgs e) { Console.WriteLine("Event Handler 0 Raised"); } static void fromMe_RaiseMe1(object sender, EventArgs e) { Console.WriteLine("Event Handler 1 Raised"); } static void fromMe_RaiseMe2(object sender, EventArgs e) { Console.WriteLine("Event Handler 2 Raised"); } public static void FireEvent(object onMe, string invokeMe, params object[] eventParams) { MulticastDelegate eventDelagate = (MulticastDelegate)onMe.GetType().GetField(invokeMe, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(onMe); Delegate[] delegates = eventDelagate.GetInvocationList(); foreach (Delegate dlg in delegates) { dlg.Method.Invoke(dlg.Target, eventParams); } } }
UPDATE
I'm not familiar with the System.Timer.Timer
class, so I'm not sure what is different from my provided example. You could perhaps try something like:
public static void FirePublicEvent(object onMe, string invokeMe, params object[] eventParams) { MulticastDelegate eventDelagate = (MulticastDelegate)onMe.GetType().GetField(invokeMe, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public).GetValue(onMe); Delegate[] delegates = eventDelagate.GetInvocationList(); foreach (Delegate dlg in delegates) { dlg.Method.Invoke(dlg.Target, eventParams); } }
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