Multicast Delegates and Events
Written by Mike James   
Friday, 24 June 2016
Article Index
Multicast Delegates and Events
Generic Events

Multicast delegates are useful in their own right but they also form the basis on which the C# event system is built. We take a close look at how they work and how to use them. For example, did you know you could add and subtract delegates?

This is a chapter of our ebook on C# - a work in progress.

Deep C#

 Buy Now From Amazon


 Chapter List

  1. Why C#?

    I Strong Typing & Type Safety
  2. Strong Typing
    Why Strong Typing
  3. Value & Reference
  4.    Extract Value And Reference
  5. Structs & Classes
    Structs & Classes 
  6. Inheritance
  7. Interfaces & Multiple Inheritance
    Extract Interface
  8. Controlling Inheritance
    II Casting & Generics
  9. Casting - The Escape From Strong Typing
    Extract Casting I ***NEW!
  10. Generics
  11. Advanced Generics
  12. Anonymous & Dynamic
    III Functions
  13. Delegates
  14. Multicast Delegates
  15. Anonymous Methods, Lambdas & Closures
    IV Async
  16. Threading, Tasks & Locking
  17. The Invoke Pattern
  18. Async Await
  19. The Parallel For
    V Data - LINQ, XML & Regular Expressions
  20. The LINQ Principle
  21. XML
  22. LINQ To XML
  23. Regular Expressions
    VI Unsafe & Interop
  24. Interop
  25. COM
  26. Custom Attributes
  27. Bit Manipulation
  28. Advanced Structs
  29. Pointers 

Extra Material




A delegate is a class that wraps a method so that it can be used in more sophisticated ways - e.g. passed as a parameter to another method. But delegates are also ways of making lists of methods that can be called in sequence when the delegate is invoked. Now that you know how delegates work its time to look at the multicast delegate and their relationship to events. 


If you look at the Framework Reference you will find a Delegate class and a class derived from it, MulticastDelegate.

In theory the Delegate class can encapsulate a single method and the MulticastDelegate maintains a list of methods and so can encapsulate more than one method.

In practice this isn’t true.

Early on in the development of the framework it was decided that Delegate and MulticastDelegate should do the same job and be merged. However merging them would have created too many problems so Delegate was left as the base class for MulticastDelegate, but the two are essentially identical.

At this point you might imagine that you would never use the Delegate class but in fact it is still returned by some methods that expect to return a single method encapsulated by a Delegate.

It also used to be the case that if you created a delegate which returned void then it was encapsulated by a MulticastDelegate but if it returned a result then a Delegate was used.

This distinction was made because of the difficult of determining which method’s return value was actually returned in a multicast invocation.  However, this was solved by simply encapsulating all methods using MutlicastDelegate and in a multicast situation the last method called is the only one that returns a result.

All delegates are MulticastDelegates but for efficiency reasons an invocation list is only created if there is more than one method encapsulated.

That is, a delegate that encapsulates a single method stores this method in its Method and Target properties and has a null invocation list.

Both of these classes are abstract and you cannot instantiate either directly – but this doesn’t mean that they aren’t of use as is explained below.

In normal use it is up to the compiler to create instances of a delegate class appropriate to encapsulate a method. Exactly how this is done can vary according to the .NET language in use.

In C# the delegate keyword creates an instance not of the Delegate class but of the MulticastDelegate class.

That is, in C# an instance of a delegate type is always an instance of a MulticastDelegate which extends the basic Delegate class to include an Invocation list which can store multiple methods.

Multicast in action

The easiest way to follow this confusing situation is to try it all out.

First we need two methods with the same signature that we can encapsulate in a suitable delegate:

public int hello(string param)
 MessageBox.Show("Hello "+param);
 return 1;

public int goodbye(string param)
 MessageBox.Show("Goodbye " + param);
 return 2;

A suitable delegate type is just:

delegate int greetType(string param);

Now we can create an instance of MulticastDelegate encapsulating two methods:

greetType DoGreet = hello;
DoGreet += goodbye;

The += operator is overloaded to add a method to the invocation list and this should be familiar to you if you have hand-coded events.

Invoking the delegate is just the same if it has single or multiple methods:

int i= DoGreet("delegates");

If the invocation list contains multiple methods then these are called in the order that they were added. Any parameters are passed to each method in turn and the final method to be called returns a value.

That is, in this case the Hello method is called with its parameter set to “delegates” then Goodbye is called with the same parameter. Only Goodbye returns a result and hence i is set to 2.

You can use anonymous methods or lambda expressions to define delegates within multicast delegates.

For example:

DoGreet += delegate(string param)
 MessageBox.Show("Goodbye " + param);
 return 2;

Or, more properly if you agree that lambda expressions should be used in preference to  anonymous methods:

DoGreet += (string param)=>
 MessageBox.Show("Goodbye " + param);
 return 2;

Notice that any unhandled exceptions that are raised by the delegates in the invocation list brings the call sequence to an end.










Last Updated ( Friday, 29 July 2016 )