In C#, I find myself occasionally wanting to register a method for an event in the middle of a dispatch of that same event. For example, if I have a class that transitions states based on successive dispatches of the same event, I might want the first state’s handler to unregister itself and register the second handler. However, I don’t want the second handler to be dispatched until the next time the event is fired.
The good news is that it looks like the Microsoft implementation of C# behaves exactly this way. The event registration syntax sugar gets replaced with a call to System.Delegate.Combine, which just concatenates the current invocation list and the new method into a separate list and assigns it to the event property. This gives me exactly the behavior I want.
So, my question is: is this guaranteed behavior by the language standard? I like to be able to run my C# code on other platforms under mono and generally want to make sure I’m not making assumptions about the language standard based on its implementation.
I couldn’t find any definitive information on MSDN.
If you’d like a specific example of what I’m talking about, here’s an example:
delegate void TestDelegate(); static event TestDelegate TestEvent; static void Main (string[] args) { TestEvent += TestDelegateInstanceFirst; TestEvent(); TestEvent(); } static void TestDelegateInstanceFirst () { Console.WriteLine('First'); TestEvent += TestDelegateInstanceSecond; } static void TestDelegateInstanceSecond () { Console.WriteLine('Second'); }
At least on Windows, the output is:
First First Second
Yes, it’s guaranteed.
From the unified C# 3.0 spec, section 15.1:
Note the ‘new invocation list’. And again in section 15.3:
Finally, MSDN for System.Delegate states:
I suspect there’s something in the CLI spec – I’ll check if you’d like, but hopefully these three have given you enough confidence 🙂