Ziff-Davis Enterprise 
DevSource: Microsoft Developer Resource
Add OnsArchitectureLanguagesTechniquesUsing VSForums
 
Home arrow Languages arrow Page 4 - Working with Delegates in C#
Working with Delegates in C#
By Joe Mayo

Rate This Article:
Add This Article To:
Working with Delegates in C# - ' Invoking Multiple Delegates '
( Page 4 of 6 )



Invoking Multiple Delegates

Among the things you can do with delegates is invoke several of them, all at the same time. Delegates have internal storage, called an invocation list, that holds multiple other delegates. Listing 3 demonstrates how to invoke multiple delegates at the same time.

Listing 3. MultipleDelegatesViaDelegates.cs

ADVERTISEMENT

    // displays a report by invoking all selected delegates
    public void DoReport(double units, UnitConversion conversions)
    {
        Console.WriteLine("\nCONVERSION REPORT\n");

        // 4.  invoke all delegates synchronously and in order
        conversions(units);

        Console.WriteLine();
    }

    static void Main()
    {
        MultipleDelegatesViaDelegates dels = new MultipleDelegatesViaDelegates();
        
        double units;
        int[] conversionTypes;

        dels.GetUserInput(out units, out conversionTypes);

        UnitConversion conversions = null;
            
        foreach (int conversionType in conversionTypes)
        {
            // 3. get delegate instances via factory method.
            conversions += dels.GetConversionMethod(conversionType);
        }

        dels.DoReport(units, conversions);

        Console.ReadLine();
    }

In Listing 3, the Main method retrieves a conversionTypes array from the GetUserInput method and iterates through each conversion type, adding each delegate returned from GetConversionMethod to the conversions delegate invocation list.

Most of the time, when invoking multiple delegates, the handler methods will be defined to return type void. This is because when they are invoked, only the last delegate in the list will return the value, which has few benefits, if any. If you need to capture results from each handler method, it's best to set up a collection or some other state object where the results could be recorded and retrieved after the delegate invocation completes.

Adding and Removing Delegates

Notice how Listing 3 uses the += syntax when adding delegates to the conversions delegate's invocation list. This is equivalent to the following:

   // 3. get delegate instances via factory method.
   conversions = conversions + dels.GetConversionMethod(conversionType);

You can add multiple delegates with the + operator. The following code shows another way to do this (assuming 3 conversion options were chosen by the user):

        conversions = 
            dels.GetConversionMethod(conversionTypes[0]) +
            dels.GetConversionMethod(conversionTypes[1]) +
            dels.GetConversionMethod(conversionTypes[2]);

You can also remove delegates with the -= operator. Here's one way to do it:

        conversions -= dels.GetConversionMethod(conversionTypes[0]);
        conversions -= dels.GetConversionMethod(conversionTypes[1]);
        conversions -= dels.GetConversionMethod(conversionTypes[2]);

Here's another way to remove the delegates that is more explicit:

        conversions -= new UnitConversion(dels.FeetToInches);
        conversions -= new UnitConversion(dels.YardsToInches);
        conversions -= new UnitConversion(dels.CentimetersToInches);

Additionally, you could use the original delegate instance to remove it from the invocation list. However, it would be wasteful to have extra delegates taking up space in your code just for this purpose. Notice, in the code above, that the new UnitConversion instantiation will remove a delegate from the conversions delegate list. If there happened to be two of the same delegate added to a delegate, then the last delegate of the type added would be the first to be removed.

When a delegate is invoked, all of its constituent delegates are invoked synchronously in the same order that they were added. To observe this behavior, run the code in Listing 3, keep track of the order in which you select conversions, and notice how the report always prints results in that order.

Another tip is to protect against the case where no constituent delegates have been added to a delegates invocation list. Before a delegate is instantiated or a delegate is assigned, its value is null. Invoking a null delegate causes a NullReferenceException exception to be thrown. You can see this by running the code in Listing 3 and selecting "Q" without selecting any other options. To deal with this, replace the raw delegate invocation in the DoReport method with the following code:

        if (conversions != null)
        {
            conversions(units);
        }
        else
        {
            Console.WriteLine("No Conversions Selected.");
        }

Doing so allows the code to handle the null condition gracefully, and ensures that an exception is not raised.



 
 
>>> More Languages Articles          >>> More By Joe Mayo
 



DevSource video
Devsource Video Series
Manipulating Society through Technology
Jeremy Bailenson, Director of the Virtual Human Interaction Lab at Stanford University, talks about virtual reality, avatars, Moore's law, how real world behaviors influence online reality, and societal manipulation through technology!
>> Play video
>> Read article
>> See all videos
DevLife Blog

Julia explores the Robotics Studio! (It's for more than you think.)

MSDev Blog

Messages for Bill Gates!

Make it Work
.NET makes runtime type checking a breeze. See what Peter has to say about it in this week's tips!
News
Microsoft Counts on App Support for Vista
Microsoft has taken pains to demonstrate that Windows Vista will have ample application support.
DevSource RSS FEEDS
XML Want an easy way to keep up with breaking tech news? And the Get DevSource headlines delivered to your desktop with RSS.