View Single Post
 
Old 09-11-2004, 05:19 AM
Deadalus Deadalus is offline
Promising Talent

Retired Moderator
* Guru *
 
Join Date: May 2002
Location: Brussels
Posts: 3,601
Default Multicast delegates

An interesting feature about delegates is that they can be "multicast", which essentially means that they can notify or trigger multiple methods.

Take the last example above and suppose that we want that a change in wealthrating not only changes the label, but triggers another, seperate procedure as well (here a simple procedure that changes the form's background color, named WealthColor). The Load procedure of our form would look something like this:
Code:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'set the delegate to the first procedure oWealth.PassDelegate(AddressOf WealthStatus) 'set it to the second procedure (as well) oWealth.PassDelegate(AddressOf WealthColor) End Sub
With our current PassDelegate procedure this won't work. Or rather, it will, but the second line will simply replace the pointer to WealthStatus in our delegate with a pointer to WealthColor.

So we need to change the PassDelegate sub in such a way that it adds a function pointer to the one present rather than replacing it. Luckily, the Delegate class has a method Combine that lets us do just that.
Code:
Public Sub PassDelegate(ByVal doDel As BankEventHandler) doWealthRating = CType([Delegate].Combine(doWealthRating, doDel), BankEventHandler) End Sub
(Side note: Don't let the square brackets confuse you. They're just there to indicate that we mean the class Delegate, and not the identically named keyword. To avoid this trickery, we could also have done this:
Code:
doWealthRating = CType(doWealthRating.Combine(doWealthRating, doDel), BankEventHandler)
where we use a Delegate object to call the Shared method Combine. I prefer not to do that, to make clear it's not an instance method we're using.)

So what's happening here? We simply take two delegates, with their own list of functions they notify, and return a new delegate, with a notification list that combines these lists. The CType is only there because Combine returns a Delegate object and we want to store it in a variable of our more specific, derived delegate type.

So now when we use PassDelegate repeatedly, like in the Load sub above, we're adding methods to our notification list. When Invoke is called, all methods in this list will execute.

Note that when the first method is passed, doWealthrating will still be Nothing. Combine is defined to then return the other passed delegate, so we don't even need to code for this special case.

It's easy to see that in our simple example, we could have just elaborated the one existing method. Or, for that matter, used a classic event. It's equally clear though, that this gives us a very elegant way to add or remove logically independent procedures that should be triggered by the same event. Moreover, the methods that a delegate triggers can be in different classes, as long as they have access to the same delegate object.

A more elaborate discussion of multicast delegates can be found here: http://msdn.microsoft.com/msdnmag/is...asicInstincts/
Attached Files
File Type: zip Delegate_Multicast.zip (6.3 KB, 183 views)

Last edited by Deadalus; 09-11-2004 at 05:31 AM.
Reply With Quote