Posted by: Cirilo Meggiolaro | 11/24/2008

Tip of the day #41 – Multicast Delegates

Multicast delegates provide functionality to execute more than one method.

Internally a linked list of delegates (called Invocation List) is stored and when the multicast delegate is invoked, the list of delegates will be executed in sequence.

How to…

The simplest way to start working with multicast delegates is to create single delegates and combine them to a multicast delegate as described on the following code snippet:

/// Declare the multicast delegate
public delegate void myDel();

static public void Main(string[] args)
{
    /// Declare the single delegate that points to MethodA
    myDel myDelA = new myDel(MethodA);

    /// Declare the single delegate that points to MethodA
    myDel myDelB = new myDel(MethodB);

    /// Declare the multicast delegate combining both delegates A and B
    myDel myMultiCast = (myDel)Delegate.Combine(myDelA, myDelB);

    /// Invoke the multicast delegate
    myMultiCast.Invoke();
}

static void MethodA()
{
    Console.WriteLine(“Executing method A.”);
}

static void MethodB()
{
    Console.WriteLine(“Executing method B.”);
}

Output:
Executing method A.
Executing method B.

Deriving a class from MulticastDelegate class

The Delegate and MulticastDelegate classes cannot be derived explicitly but there’s a way to do that.

The following example defines three classes named Order, Stock and Receipt beyond the main method from a console application for example:

1. The Order class holds the delegate that defines the methods signature and provides methods to add product items to the order and a checkout method that will use a delegate as parameter to define what method to call. It can be used for single delegates or a multicast delegate.

2. The Stock class has an operation to remove the products from stock;

3. The Receipt class has an operation to print an item to the receipt;

4. The Main method creates an instance of the Order type, adding product items to the order and creates the multicast delegate based in a combination of two derived delegates.

Let’s check the code:

class Order
{
    /// Main order delegate
    public delegate void myOrderDel(int prodId, int quantity);

    /// Stores a dictionary of products ids and respective quantities
    private static HybridDictionary prodList = new HybridDictionary();

    public void AddItem(int prodId, int quantity)
    {
        /// Add products and quantitites to the dictionary.
        
prodList.Add(prodId, quantity);
    }

    public static void Checkout(myOrderDel multicastDelegate)
    {
        /// Loop through all products in the dictionary
        foreach (DictionaryEntry prod in prodList)
        {
            /// Invoke the multicast delegate
            multicastDelegate.Invoke(Convert.ToInt32(prod.Key), Convert.ToInt32(prod.Value));
        }
    }
}

class Stock
{
    public static void Remove(int prodId, int quantity)
    {
        Console.WriteLine(“{0} unit(s) of the product {1} has/have been removed from the stock.”, quantity, prodId);
    }
}

class Receipt
{
    public static void PrintItem(int prodId, int quantity)
    {
        Console.WriteLine(“{0} unit(s) of the product {1} has/have been printed to the receipt.”, quantity, prodId);
    }
}

static public void Main(string[] args)
{
    /// Create the order object
    Order myOrder = new Order();

    /// Add products and quantities to the order
    myOrder.AddItem(1, 2);
    myOrder.AddItem(2, 3);
    myOrder.AddItem(3, 1);
    myOrder.AddItem(4, 1);
    myOrder.AddItem(5, 4);

    /// Order delegate instance pointing to Stock class.
    Order.myOrderDel myStockDel = new Order.myOrderDel(Stock.Remove);

    /// Receipt delegate instance pointing to Receipt class.
    Order.myOrderDel myReceiptDel = new Order.myOrderDel(Receipt.PrintItem);

    /// Combine the two previous delegates onto the multicast delegate.
    Order.myOrderDel myMulticastDel = (Order.myOrderDel)Delegate.Combine(myStockDel, myReceiptDel);

    /// Invoke the checkout method passing the multicast delegate
    Order.Checkout(myMulticastDel);
}

Output:
2 unit(s) of the product 1 has/have been removed from the stock.
2 unit(s) of the product 1 has/have been printed to the receipt.
3 unit(s) of the product 2 has/have been removed from the stock.
3 unit(s) of the product 2 has/have been printed to the receipt.
1 unit(s) of the product 3 has/have been removed from the stock.
1 unit(s) of the product 3 has/have been printed to the receipt.
1 unit(s) of the product 4 has/have been removed from the stock.
1 unit(s) of the product 4 has/have been printed to the receipt.
4 unit(s) of the product 5 has/have been removed from the stock.
4 unit(s) of the product 5 has/have been printed to the receipt.

The MSDN site provides another nice example about how to derive a class (not in an explicitly way) from MulticastDelegate class. Click here to read!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: