On Thu, 2002-07-11 at 09:11, Nick Drochak wrote: > | -----Original Message----- > | From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]]On > | Behalf Of Dietmar Maurer > | Sent: Thursday, July 11, 2002 3:22 PM > | > | On Thu, 2002-07-11 at 06:52, Yuan-Fen Eric Kuo || 郭源汾 wrote: > | > I am new to the thread so please forgive me if it has been > | discussed or I > | > have missed some points somewhere. > | > > | > It seems that delegate invokes the methods in the reversed order as they > | > were combined. According to MS's Spec. isn't it supposed to > | invoke methods > | > from the left to right of the operator? > | > | Yes, I think we should not reverse the order. Do you have some tests to > | show that behavior? > > I just read in a few of places over the past couple of days that the order is not >guaranteed and one should not depend on it. > > Does someone have information otherwise?
i can assure you the order should be guaranteed, the same order in which the individual combination of addition/removal suggests. just what one would expect. same goes for MS. the documentation remains comparably precise in this respect, once you've sorted out the blurry stuff (the MS class design isn't all that well). haven't looked again into it for quite some time now. though, i can't replicate above problem just by trying from simple examples. maybe the original question derived from browsing the source code? mono keeps multicastdelegate chains linked in a recursive manner, i.e. each multicastdelegate simply keeps a single link to another one or null (as opposed to encapsulated arraylists or whatever). the internal chaining is indeed _reverted_. i.e. the internal link is a prev-pointer, not a next pointer. why? removal. consider removing an invocation chain from another. now the fun part is that not the first occurence of the list to remove is removed but the _last_ occurence. might have originated at MS from a side effect. but it's documented in the class docs nonetheless. removals are therefore implemented in mono by reverting the internal order for speed. ::Invoke() then recurses depth-first through the chain, which gets you back to the expected order during invocation. eats up some stack space, but i can't think of a more elegant way. summary, for a bundle of delegates of type foo(int): (a + b + c)(42) invokes a -> b -> c. (a + b + c - b)(42) invokes a -> c. (a + b + c + a + b - (a + b))(42) invokes a -> b -> c, not c -> a -> b. ever. i've spent quite some time until i got this right. pleaso drop me a note if any problems arise. i remember having checked in unit tests for this, though. regards, dns -- ___________________________________________________________________________ mailto:[EMAIL PROTECTED] _______________________________________________ Mono-list maillist - [EMAIL PROTECTED] http://lists.ximian.com/mailman/listinfo/mono-list
