   Event vs. Delegates
  Hello y'all,I have some questions that basically prove my un-awareness about the .NET mode (and that also prove that I don't have the spec here, and that I'mo too lazy to download it): 1) what are the differences between events and delegates? As I see this, an even is a collection of delegates. 2) if an event is a collection of delegates, in what order are the delegates executed? I guess they are executed in either the registration order of the inverse registration order...3) if I have to implement a system that should process events sequentially until one of them return a specific code, how to handle that using events? should I implement that by myself (some kind of new event type with an overloaded operator +=)Thanks for your answers?   
  An event is the object that is used to signal the delegates that are attached to the event. To be pedantic I believe that an event object only holds a reference to a single delegate; which turns out to be a MulticastDelegate, which in turn stores the other delegates.Since a MulticastDelegate is a class you can then use MulticastDelegate.GetInvocationList() to find the order that the attached delegates will be invoked. I believe it's in order of attachment by default, but right now I can't find an official source to back that up.Idiomatically to use an event to signal delegates until something breaks the chain, you would use a CancelEventArgs argument for your delegates (or something derived from CancelEventArgs) and invoke along the GetInvocationList() until something sets the Cancel member of the argument. Something like  void OnMyEvent() {    if (MyEvent != null) { CancelEventArgs args = new CancelEventArgs(); foreach (DelegateType listener in MyEvent.GetInvocationList()) {   listener(args);   if (args.Cancel) break; }    }  }You can vary this by having your DelegateType return a bool, int, etc. rather than check the args.Cancel.   ;Quote:Original post by Emmanuel DelogetHello y'all,I have some questions that basically prove my un-awareness about the .NET mode (and that also prove that I don't have the spec here, and that I'mo too lazy to download it): 1) what are the differences between events and delegates? As I see this, an even is a collection of delegates.Hmm... This MSDN article, Events and Delegates explains things in a rather good detail. You can regard delegates as syntactic sugar for type-safe function pointer for doing callbacks without Java styled interfaces. If you search through the web for examples, note that .NET 1.1 syntax is different than the present .NET 2.0+ syntax. Search specifically for that if you want see code examples.Quote:2) if an event is a collection of delegates, in what order are the delegates executed? I guess they are executed in either the registration order of the inverse registration order... In general in the order in which they were added. Don't count on this behaviour though. Please see article Multicast Delegate Internals.Quote:3) if I have to implement a system that should process events sequentially until one of them return a specific code, how to handle that using events? should I implement that by myself (some kind of new event type with an overloaded operator +=)I didn't understand this one. If you want sequential callbacks, doing that with delegates won't really work (see the link on multicast delegates). In any case, it is a normal practice to define new event and delegate types. [smile]After reading those articles and perhaps searching for more information yourself based on the information provided by them, you should be somewhat wiser.   ;  For number three, can you throw an exception and just have it caught by whatever activates the event? Seems like more of a hack than SiCrane's, but I would expect it to work nicely.   ;Quote:Original post by Emmanuel Deloget1) what are the differences between events and delegates? As I see this, an even is a collection of delegates. No. All delegates act as collections of methods. The event keyword is a modifier which makes the operators += and -= public, while making everything else about the delegate protected.Quote:2) if an event is a collection of delegates, in what order are the delegates executed? I guess they are executed in either the registration order of the inverse registration order...I cannot find it in the spec, but I am nearly certain that it's registration order.Quote:3) if I have to implement a system that should process events sequentially until one of them return a specific code, how to handle that using events? should I implement that by myself (some kind of new event type with an overloaded operator +=)You can't overload that operator in C#. All sort of assignment is off-limits in C#, making stuff like that infeasible. Further, you can't inherit from System.Delegate or implement operator() making things even worse.There's two options.1. Make something more like a container and less like a delegate. This works pretty well, though is a little awkward and quite java-delegate-like. Plus you'll be generally unable to make it generic enough to take arbitrary signatures and generate type-safe calling mechanisms for your shortcut-delegate.2. (Highly ugly) Since running through a delegate's invocation list stops when you hit an exception you could do some sort of construct which (mis)uses that to your advantage.[edit: way, way, way, too slow...]   ;Quote:The event keyword is a modifier which makes the operators += and -= public, while making everything else about the delegate protected.Just being nitpicky here, but that should read while making everything else about the delegate private.  Events cannot be invoked in derived classes; the usual procedure to provide protected access to an event is to create a protected OnEventName method which invokes the event. Quote:Quote:3) if I have to implement a system that should process events sequentially until one of them return a specific code, how to handle that using events? should I implement that by myself (some kind of new event type with an overloaded operator +=)You can't overload that operator in C#. All sort of assignment is off-limits in C#, making stuff like that infeasible. Further, you can't inherit from System.Delegate or implement operator() making things even worse.You can actually change the += / -= behavior with events, through a syntax similar to that used for properties:public event MyDelegateType EventName{    add    { /* code to be executed when EventName += MyFunction line is called */ }    remove    { /* code to be executed when EventName -= MyFunction line is called */ }}If you do this you have to provide your own delegate storage for the event, and you can no longer use the event as if it were a delegate for invoking it, calling GetInvokationList, etc. (you use your own storage instead).   ;Quote:Original post by kanatoQuote:The event keyword is a modifier which makes the operators += and -= public, while making everything else about the delegate protected.Just being nitpicky here, but that should read while making everything else about the delegate private.  Events cannot be invoked in derived classes; the usual procedure to provide protected access to an event is to create a protected OnEventName method which invokes the event. Quote:Quote:3) if I have to implement a system that should process events sequentially until one of them return a specific code, how to handle that using events? should I implement that by myself (some kind of new event type with an overloaded operator +=)You can't overload that operator in C#. All sort of assignment is off-limits in C#, making stuff like that infeasible. Further, you can't inherit from System.Delegate or implement operator() making things even worse.You can actually change the += / -= behavior with events, through a syntax similar to that used for properties:*** Source Snippet Removed ***If you do this you have to provide your own delegate storage for the event, and you can no longer use the event as if it were a delegate for invoking it, calling GetInvokationList, etc. (you use your own storage instead).Ah yes, always forget that...Ah, thankye for the clarification. Rating++  :]   ;  For #3, look at "CancelEventHandler" and "CancelEventArgs" for the cleanest example.  This doesn't allow you to simply avoid calling all handlers in the handler list, but does allow you to do complex things like 'returning' values or doing early bail-out in other event handlers.(More info)  CancelEventHandler is used for things like locking focus on a textbox until it successfully validates.  In that case, the call sequence looks like:(TextBox)CancelEventArgs cea = new CancelEventArgs();OnValidating(cea);(OnValidating raises Validating event)Handler A sees that the user entered something invalid, so it sets cancelEventArgs.Cancel = true.Handler B can check to see if Cancel == true.  If it is, don't bother validating and just return immediately.  If it is false, then do additional validation.  OR, you could have Handler B check anyway and set the value back to false if it succeeds validating using a different check (if you wanted the textbox to validate under EITHER condition).Control finally returns to the TextBox internal code, which then checks the final value of Validating and uses that to either cancel the input focus change or allow it to continue.If generic<T> classes could constrain T on the delegate type (they can't), you could write your own custom Event<T> class to do the bailout for you.   ;  Well, thanks to all of you! (and r++ to those I haven't rated yet)I played a bit with events in my project 2 implementation (so that adding or removing a modifier to a ModifiableScore (the base class for D20.HitPoints, D20.SavingThrow, D20.Abilities, D20.Skill and many more to come) triggers the call of a delegate. Seems like a nice system to me. However, I find it disturbing that you have to check whether an event is null (ie noone registered any delegate) before calling it. Did I missed something?   ;Quote:Original post by Emmanuel DelogetWell, thanks to all of you! (and r++ to those I haven't rated yet)I played a bit with events in my project 2 implementation (so that adding or removing a modifier to a ModifiableScore (the base class for D20.HitPoints, D20.SavingThrow, D20.Abilities, D20.Skill and many more to come) triggers the call of a delegate. Seems like a nice system to me. However, I find it disturbing that you have to check whether an event is null (ie noone registered any delegate) before calling it. Did I missed something?When I'm at home I will fetch up source since I do similar OnChange triggers for my equivalent of ModifiableScore (CumulativeValue)As for the null delegate, I don't know of any way to do noop by default. That is (imo) terribly annoying but can kinda be circumvented by default assigning the noop to the event. That process can be made a little less tedious with generics. I'll look to post code when I have access to it again.   