5.6 Return Values for Multicast Delegates

 <  Day Day Up  >  

You want to access individual return values for each delegate method within a multicast delegate.


If you want to use the return value from one delegate method as the input to another delegate method within the same multicast delegate, create a parameter prefaced with the ref keyword for value types. If an object is passed as a parameter, note that any change to that object is passed onto the next delegate method within the invocation list:

 public void Factorial( ref int op1, ref int op2 ); 

If you want to obtain individual return values for each single delegate within a multicast delegate, you can create a collection as a parameter in the delegate list that method implementations can use to place return values as demonstrated in Listing 5.3.

Listing 5.3 Allowing Individual Delegate Return Values by Using a Collection
 using System; using System.Collections; using System.Text; namespace _6_ReturnValues {     public delegate bool PrintString( string s, ArrayList retVals );     class Class1     {         [STAThread]         static void Main(string[] args)         {             ArrayList retVals = new ArrayList();             // instantiate delegate             PrintString[] printDelegates = new PrintString[2];             PrintString stringPrinters;             printDelegates[0] = new PrintString( NormalPrint );             printDelegates[1] = new PrintString( FirstCharPrint );             stringPrinters = (PrintString) Delegate.Combine( printDelegates );             // get string from user             Console.Write( "Enter a string: " );             string input = Console.ReadLine();             stringPrinters( input, retVals );             foreach( string ret in retVals )             {                 Console.WriteLine( ret );             }         }         static bool NormalPrint( string s, ArrayList retVals )         {             retVals.Add( s );             return true;         }         static bool FirstCharPrint( string s, ArrayList retVals )         {             StringBuilder retVal = new StringBuilder();             string[] splitStrings = s.Split( new char[]{' '} );             foreach( string splitString in splitStrings )             {                 retVal.Append(splitString[0]);                 for( int i = 0; i < splitString.Length; i++ )                     retVal.Append( " " );             }             retVals.Add( retVal.ToString() );             return true;         }     } } 


One of the limitations of using a multicast delegate is the lack of information based on a return value from the individual methods bound to that multicast delegate. The return value from a multicast delegate is the result of the last delegate method called within the invocation list. You are therefore unable to access the previous delegate method return values without resorting to the special programming methods presented here.

Although not necessarily capturing the return value of each delegate, using the ref keyword on a parameter allows you to carry changes to a value type to each subsequent delegate. This move can be useful, for instance, if you need a value that each delegate must change and that change must be carried over. In the Factorial method header declared earlier, you can create a factorial function that multiplies the first parameter by the last result and then decrements the first parameter by one. The multicast delegate would contain a instance of that delegate equal to the initial value of the original first parameter. Of course, this process is highly inefficient, but it does a good job of showing how to carry value types across multiple delegates within a multicast delegate.

If you would rather obtain information individually from each delegate, then you can create an array to store that information. Although it's not the most elegant solution, there aren't many other choices to solve this problem. Listing 5.3 uses an ArrayList as a parameter to the delegate. As each delegate method is invoked, it places its result at the end of the list. You can then access each delegate's result after the multicast delegate has finished calling each method within its invocation list. We used an ArrayList due to its ability to grow if the size of the array is unknown, but you can just as easily use a regular system array. Furthermore, you can pass multiple return values by using a structure that contains the return values as the item data type within the array. Finally, it's worth noting that because ArrayList is an object and not a value type, you do not need the ref keyword because objects are passed by reference by default.

 <  Day Day Up  >  

Microsoft Visual C# .Net 2003
Microsoft Visual C *. NET 2003 development skills Daquan
ISBN: 7508427505
EAN: 2147483647
Year: 2003
Pages: 440

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net