Two delegates

   

/*
 * C# Programmers Pocket Consultant
 * Author: Gregory S. MacBeth
 * Email: gmacbeth@comporium.net
 * Create Date: June 27, 2003
 * Last Modified Date:
 */
using System;

namespace Client.Chapter_8___Delegates_and_Events
{
  public class DelegatesChapter_8___Delegates_and_Events
  {
    delegate int MyDelegate(string s);
    static void Main(string[] args)
    {
      MyDelegate Del1 = new MyDelegate(DoSomething);
      MyDelegate Del2 = new MyDelegate(DoSomething2);
      string MyString = "Hello World";

      Del1(MyString);
      Del2(MyString);

      //Or you can Multicast delegates by doing this
      MyDelegate Multicast = null;

      Multicast += new MyDelegate(DoSomething);
      Multicast += new MyDelegate(DoSomething2);

      //Both DoSomething & DoSomething2 will be fired
      //in the order they are added to the delegate
      Multicast(MyString);
      Multicast -= new MyDelegate(DoSomething2);
    }
    static int DoSomething(string s)
    {
      return 0;
    }
    static int DoSomething2(string s)
    {
      return 0;
    }
  }
}

           
          


Delegates can refer to instance methods, too


   

/*
C#: The Complete Reference 
by Herbert Schildt 

Publisher: Osborne/McGraw-Hill (March 8, 2002)
ISBN: 0072134852
*/


// Delegates can refer to instance methods, too. 
  
using System; 
 
// Declare a delegate.  
delegate string strMod(string str); 

class StringOps {
  // Replaces spaces with hyphens. 
  public string replaceSpaces(string a) { 
    Console.WriteLine("Replaces spaces with hyphens."); 
    return a.Replace(' ', '-'); 
  }  
 
  // Remove spaces. 
  public string removeSpaces(string a) { 
    string temp = ""; 
    int i; 
 
    Console.WriteLine("Removing spaces."); 
    for(i=0; i < a.Length; i++) 
      if(a&#91;i&#93; != &#039; &#039;) temp += a&#91;i&#93;; 
 
    return temp; 
  }  
 
  // Reverse a string. 
  public string reverse(string a) { 
    string temp = ""; 
    int i, j; 
 
    Console.WriteLine("Reversing string."); 
    for(j=0, i=a.Length-1; i >= 0; i--, j++) 
      temp += a[i]; 
 
    return temp; 
  } 
} 
 
public class DelegateTest1 {   
  public static void Main() { 
    StringOps so = new StringOps(); // create an instance of StringOps
 
    // Construct a delegate. 
    strMod strOp = new strMod(so.replaceSpaces); 
    string str; 
 
    // Call methods through delegates. 
    str = strOp("This is a test."); 
    Console.WriteLine("Resulting string: " + str); 
    Console.WriteLine(); 
      
    strOp = new strMod(so.removeSpaces); 
    str = strOp("This is a test."); 
    Console.WriteLine("Resulting string: " + str); 
    Console.WriteLine(); 
 
    strOp = new strMod(so.reverse); 
    str = strOp("This is a test."); 
    Console.WriteLine("Resulting string: " + str); 
  } 
}


           
          


A simple delegate example


   

/*
C#: The Complete Reference 
by Herbert Schildt 

Publisher: Osborne/McGraw-Hill (March 8, 2002)
ISBN: 0072134852
*/


// A simple delegate example.  
  
using System; 
 
// Declare a delegate.  
delegate string strMod(string str); 
 
public class DelegateTest { 
  // Replaces spaces with hyphens. 
  static string replaceSpaces(string a) { 
    Console.WriteLine("Replaces spaces with hyphens."); 
    return a.Replace(&#039; &#039;, &#039;-&#039;); 
  }  
 
  // Remove spaces. 
  static string removeSpaces(string a) { 
    string temp = ""; 
    int i; 
 
    Console.WriteLine("Removing spaces."); 
    for(i=0; i < a.Length; i++) 
      if(a&#91;i&#93; != &#039; &#039;) temp += a&#91;i&#93;; 
 
    return temp; 
  }  
 
  // Reverse a string. 
  static string reverse(string a) { 
    string temp = ""; 
    int i, j; 
 
    Console.WriteLine("Reversing string."); 
    for(j=0, i=a.Length-1; i >= 0; i--, j++) 
      temp += a[i]; 
 
    return temp; 
  } 
     
  public static void Main() {  
    // Construct a delegate. 
    strMod strOp = new strMod(replaceSpaces); 
    string str; 
 
    // Call methods through the delegate. 
    str = strOp("This is a test."); 
    Console.WriteLine("Resulting string: " + str); 
    Console.WriteLine(); 
      
    strOp = new strMod(removeSpaces); 
    str = strOp("This is a test."); 
    Console.WriteLine("Resulting string: " + str); 
    Console.WriteLine(); 
 
    strOp = new strMod(reverse); 
    str = strOp("This is a test."); 
    Console.WriteLine("Resulting string: " + str); 
  } 
}


           
          


Demonstrate using a static delegate without declaring an instance of the class


   


/*
C# Programming Tips &amp; Techniques
by Charles Wright, Kris Jamsa

Publisher: Osborne/McGraw-Hill (December 28, 2001)
ISBN: 0072193794
*/
// StaticDl.cs -- Demonstrate using a static delegate without declaring
//                an instance of the class.
//
//                Compile this program with the following command line:
//                    C:>csc StaticDl.cs
using System;

namespace nsDelegates
{
    public class StaticDl
    {
        public delegate void StringHandler (string str);
        static public StringHandler DoString;

        static public void Main ()
        {
// Create a delegate in this class
            DoString = new StringHandler (ShowString);
            DoString ("Static delegate called");
//
// Show that the static constructor in another class is shared by instances
            clsDelegate.DoMath = new clsDelegate.MathHandler (SquareRoot);
            clsDelegate dlg1 = new clsDelegate (49);
            clsDelegate dlg2 = new clsDelegate (3.14159);
        }
// The method used with the string delegate
        static private void ShowString (string str)
        {
            Console.WriteLine (str);
        }
// The method used with the double delegate
        static private double SquareRoot (double val)
        {
            double result = Math.Sqrt (val);
            Console.WriteLine ("The square root of " + val + " is " + result);
            return (result);
        }
    }
    class clsDelegate
    {
        public delegate double MathHandler (double val);
        static public MathHandler DoMath;
// The constructor invokes the delegate if it is not null.
        public clsDelegate (double val)
        {
            value = val;
            if (DoMath != null)
                sqrt = DoMath (value);
        }
        double value;
        double sqrt = 0;
    }
} 



           
          


Using a delegate with a container class to sort the collection and return a sorted array using different sort criteria


   


/*
C# Programming Tips &amp; Techniques
by Charles Wright, Kris Jamsa

Publisher: Osborne/McGraw-Hill (December 28, 2001)
ISBN: 0072193794
*/
 
// SortEmpl.cs -- Demonstrates using a delegate with a container class to
//                sort the collection and return a sorted array using different
//                sort criteria.
//
//                Compile this program with the following command line:
//                    C:>csc SortEmpl.cs
using System;
using System.ComponentModel;

namespace nsDelegates
{

    public class SortEmpl
    {
        // Declare an enum for the sort methods.
        enum SortBy {Name, ID, ZIP};
        // Create a container to get the clsEmployee object collection
        static public clsEmployeeContainer container = new clsEmployeeContainer ();
        static public void Main ()
        {
            container.Add (new clsEmployee ("John", "Smith", "87678", 1234));
            container.Add (new clsEmployee ("Marty", "Thrush", "80123", 1212));
            container.Add (new clsEmployee ("Milton", "Aberdeen", "87644", 1243));
            container.Add (new clsEmployee ("Marion", "Douglas", "34567", 3454));
            container.Add (new clsEmployee ("Johnathon", "Winters", "53422", 3458));
            container.Add (new clsEmployee ("William", "Marmouth", "12964", 3658));
            container.Add (new clsEmployee ("Miles", "O&#039;Brien", "63445", 6332));
            container.Add (new clsEmployee ("Benjamin", "Sisko", "57553", 9876));

            // Show the unsorted employee list.
            Console.WriteLine ("Unsorted employee list:");
            ComponentCollection collectionList = container.GetEmployees();
            foreach (clsEmployee emp in collectionList)
            {
                Console.WriteLine ("	" + emp);
            }

            // Sort the employees by last name and show the list.
            Console.WriteLine ("
Sorted by last name:");
            clsEmployee [] arr = SortList (SortBy.Name);
            foreach (clsEmployee emp in arr)
            {
                Console.WriteLine ("	" + emp);
            }

            // Sort the employees by ID number and show the list.
            Console.WriteLine ("
Sorted by employee ID:");
            arr = SortList (SortBy.ID);
            foreach (clsEmployee emp in arr)
            {
                Console.WriteLine ("	" + emp);
            }

            // Sort the employees by ZIP code and show the list.
            Console.WriteLine ("
Sorted by ZIP code:");
            arr = SortList (SortBy.ZIP);
            foreach (clsEmployee emp in arr)
            {
                Console.WriteLine ("	" + emp);
            }
        }
        // Define a method that will create the proper delegate according to
        // the sort that is needed.
        static clsEmployee [] SortList (SortBy iSort)
        {
            clsEmployeeContainer.CompareItems sort = null;
            switch (iSort)
            {
                case SortBy.Name:
                    sort = new clsEmployeeContainer.CompareItems(clsEmployee.CompareByName);
                    break;
                case SortBy.ID:
                    sort = new clsEmployeeContainer.CompareItems(clsEmployee.CompareByID);
                    break;
                case SortBy.ZIP:
                    sort = new clsEmployeeContainer.CompareItems(clsEmployee.CompareByZip);
                    break;
            }
            // Do the sort and return the sorted array to the caller.
            return (container.SortItems (sort, false));
        }
    }

    public class clsEmployee : Component
    {
        // Define an employee class to hold one employee&#039;s information.
        public clsEmployee (string First, string Last, string Zip, int ID)
        {
            FirstName = First;
            LastName = Last;
            EmployeeID = ID;
            ZipCode = Zip;
        }
        public string  FirstName;
        public string  LastName;
        public string  ZipCode;
        public int      EmployeeID;

        // Define a method to sort by name
        static public int CompareByName (object o1, object o2)
        {
            clsEmployee emp1 = (clsEmployee) o1;
            clsEmployee emp2 = (clsEmployee) o2;
            return (String.Compare (emp1.LastName, emp2.LastName));
        }

        // Define a method to sort by ZIP code
        static public int CompareByZip (object o1, object o2)
        {
            clsEmployee emp1 = (clsEmployee) o1;
            clsEmployee emp2 = (clsEmployee) o2;
            return (String.Compare (emp1.ZipCode, emp2.ZipCode));
        }

        // Define a method to sort by employee ID number.
        static public int CompareByID (object o1, object o2)
        {
            clsEmployee emp1 = (clsEmployee) o1;
            clsEmployee emp2 = (clsEmployee) o2;
            return (emp1.EmployeeID - emp2.EmployeeID);
        }
        // Override ToString() for diagnostic purposes
        public override string ToString ()
        {
            return (FirstName + " " + LastName + ", ZIP " + ZipCode + ", ID "  + EmployeeID);
        }
    }

    // Derive a class to hold the clsEmployee objects
    public class clsEmployeeContainer
    {
        private Container cont = new Container();
        public void Add (clsEmployee empl)
        {
            cont.Add (empl);
        }
        // Declare an array to return to the caller
        clsEmployee [] arrEmployee;

        // Declare a delegate to compare one employee object to another
        public delegate int CompareItems (object obj1, object obj2);

        // Define a sort function that takes a delegate as a parameter. The Reverse
        // parameter can be used to reverse the sort.
        public clsEmployee [] SortItems (CompareItems sort, bool Reverse)
        {
            // Get the clsEmployee objects in the container.
            ComponentCollection employees = cont.Components;
            // Create an array large enough to hold the references
            arrEmployee = new clsEmployee[employees.Count];
            // Copy the collection into the reference. The Container class will not
            // let us sort the collection itself.
            employees.CopyTo (arrEmployee, 0);

            // Do a simple bubble sort. There are more efficient sorting algorithms,
            // but a simple sort is all we need.
            while (true)
            {
                int sorts = 0;
                for (int x = 0; x < arrEmployee.Length - 1; ++x)
                {
                   int result;
                    // Sort in the reverse order if if the Reverse parameter equals true
                   if (Reverse == true)
                       result = sort (arrEmployee&#91;x + 1&#93;, arrEmployee&#91;x&#93;);
                   else
                       result = sort (arrEmployee&#91;x&#93;, arrEmployee&#91;x + 1&#93;);
                    // Reverse the two elements if the result is greater than zero
                   if (result > 0)
                   {
                       clsEmployee temp = arrEmployee[x];
                       arrEmployee[x] = arrEmployee[x+1];
                       arrEmployee[x+1] = temp;
                       ++sorts;
                   }
                }
                // If we did no sorts on this go around, the sort is complete.
                if (sorts == 0)
                    break;
            }
            // Return the sorted array to the caller.
            return (arrEmployee);
        }
        // Return the collection to the caller.
        public ComponentCollection GetEmployees ()
        {
            return (cont.Components);
        }
    }
}



           
          


Demonstrates adding multiple methods to a delegate


   


/*
C# Programming Tips &amp; Techniques
by Charles Wright, Kris Jamsa

Publisher: Osborne/McGraw-Hill (December 28, 2001)
ISBN: 0072193794
*/
 
// MultiDlg.cs -- Demonstrates adding multiple methods to a delegate.
//
//                Compile this program with the following command line
//                    C:>csc MultiDlg.cs
using System;

namespace nsDelegates
{
    public class MultiDlg
    {
        public delegate void MultiMethod ();

        static public void Main ()
        {
            MultiMethod dlg;
// Assign the first method to the delegate.
            dlg = new MultiMethod (FirstDelegate);
// Call it to show the first method is being called
            dlg ();
// Add a second method to the delegate.
            dlg += new MultiMethod (SecondDelegate);
// Call it to show both methods execute.
            Console.WriteLine ();
            dlg ();
// Remove the first method from the delegate.
            dlg -= new MultiMethod (FirstDelegate);
// Call it to show that only the second method executes
            Console.WriteLine ();
            dlg ();
        }
        static public void FirstDelegate()
        {
            Console.WriteLine ("First delegate called");
        }
        static public void SecondDelegate()
        {
            Console.WriteLine ("Second delegate called");
        }
    }
}



           
          


Demonstrate getting and printing the invocation list for a delegate


   

/*
C# Programming Tips &amp; Techniques
by Charles Wright, Kris Jamsa

Publisher: Osborne/McGraw-Hill (December 28, 2001)
ISBN: 0072193794
*/

// InvkList.cs -- Demonstrate getting and printing the invocation list
//                for a delegate.
//
//                Compile this program with the following command line:
//                    C:>csc InvkList.cs
using System;
using System.Reflection;

namespace nsDelegates
{
    public class DelegatesList
    {
        public delegate void ListHandler ();
        public ListHandler DoList;
        static public void Main ()
        {
            DelegatesList main = new DelegatesList ();
            main.DoList += new ListHandler (DelegateMethodOne);
            main.DoList += new ListHandler (DelegateMethodThree);
            main.DoList += new ListHandler (DelegateMethodTwo);
            Delegate [] dlgs = main.DoList.GetInvocationList ();
            foreach (Delegate dl in dlgs)
            {
                MethodInfo info = dl.Method;
                Console.WriteLine (info.Name);
                info.Invoke (main, null);
            }
        }
        static void DelegateMethodOne ()
        {
            Console.WriteLine ("In delegate method one");
        }
        static void DelegateMethodTwo ()
        {
            Console.WriteLine ("In delegate method two");
        }
        static void DelegateMethodThree ()
        {
            Console.WriteLine ("In delegate method three");
        }
    }
}