/* C# Programming Tips & Techniques by Charles Wright, Kris Jamsa Publisher: Osborne/McGraw-Hill (December 28, 2001) ISBN: 0072193794 */ // DlgOps.cs -- demonstrates combining and removing delegates to create // new delegates. // // Compile this program with the following command line: // C:>csc DlgOps.cs using System; namespace nsDelegates { public class DelegatesSample { public delegate void MathHandler (double val); static public void Main () { DelegatesSample main = new DelegatesSample (); MathHandler dlg1, dlg2, dlg3; dlg1 = new MathHandler (main.TheSquareRoot); dlg2 = new MathHandler (main.TheSquare); dlg3 = new MathHandler (main.TheCube); // Combine the delegates so you can execute all three at one on one value MathHandler dlgCombo = dlg1 + dlg2 + dlg3; Console.WriteLine ("Executing the combined delegate"); dlgCombo (42); // Now remove the second delegate MathHandler dlgMinus = dlgCombo - dlg2; Console.WriteLine (" Executing the delegate with the second removed"); dlgMinus (42); // Show that the individual delegates are stil available // Execute the delegates one at a time using different values Console.WriteLine (" Execute the delegates individually:"); dlg1 (64); dlg2 (12); dlg3 (4); } public void TheSquareRoot (double val) { Console.WriteLine ("The square root of " + val + " is " + Math.Sqrt (val)); } public void TheSquare (double val) { Console.WriteLine ("The square of " + val + " is " + val * val); } public void TheCube (double val) { Console.WriteLine ("The cube of " + val + " is " + val * val * val); } } }
Language Basics
Demonstrates a simple form of a delegate
/* C# Programming Tips & Techniques by Charles Wright, Kris Jamsa Publisher: Osborne/McGraw-Hill (December 28, 2001) ISBN: 0072193794 */ // SimpDlgt.cs -- Demonstrates a simple form of a delegate // // Compile this program using the following command line: // C:>csc SimpDlgt.cs using System; namespace nsDelegate { // Declare the delegate. This actually creates a new class definition. delegate double MathOp (double value); public class SimpDlgt { static public void Main () { // Declare an object of the delegate type. MathOp DoMath; // Create the delgate object using a method name. DoMath = new MathOp (GetSquare); // Execute the delegate. This actually calls the Invoke() method. double result = DoMath (3.14159); // Show the result. Console.WriteLine (result); // Assign another method to the delegate object DoMath = new MathOp (GetSquareRoot); // Call the delegate again. result = DoMath (3.14159); // Show the result. Console.WriteLine (result); } // Return the square of the argument. static double GetSquare (double val) { return (val * val); } // Return the square root of the argument. static double GetSquareRoot (double val) { return (Math.Sqrt (val)); } } }
illustrates the use of a delegate that calls object methods
/* Mastering Visual C# .NET by Jason Price, Mike Gunderloy Publisher: Sybex; ISBN: 0782129110 */ /* Example12_3.cs illustrates the use of a delegate that calls object methods */ using System; // declare the DelegateCalculation delegate class public delegate string DelegateDescription(); // declare the Person class class Person { // declare two private fields private string name; private int age; // define a constructor public Person(string name, int age) { this.name = name; this.age = age; } // define a method that returns a string containing // the person's name and age public string NameAndAge() { return(name + " is " + age + " years old"); } } // declare the Car class class Car { // declare two private fields private string model; private int topSpeed; // define a constructor public Car(string model, int topSpeed) { this.model = model; this.topSpeed = topSpeed; } // define a method that returns a string containing // the car's model and top speed public string MakeAndTopSpeed() { return("The top speed of the " + model + " is " + topSpeed + " mph"); } } public class Example12_3 { public static void Main() { // create a Person object named myPerson Person myPerson = new Person("Jason Price", 32); // create a delegate object that calls myPerson.NameAndAge() DelegateDescription myDelegateDescription = new DelegateDescription(myPerson.NameAndAge); // call myPerson.NameAndAge() through myDelegateDescription string personDescription = myDelegateDescription(); Console.WriteLine("personDescription = " + personDescription); // create a Car object named myCar Car myCar = new Car("MR2", 140); // set myDelegateDescription to call myCar.MakeAndTopSpeed() myDelegateDescription = new DelegateDescription(myCar.MakeAndTopSpeed); // call myCar.MakeAndTopSpeed() through myDelegateDescription string carDescription = myDelegateDescription(); Console.WriteLine("carDescription = " + carDescription); } }
illustrates the use of a multicast delegate
/* Mastering Visual C# .NET by Jason Price, Mike Gunderloy Publisher: Sybex; ISBN: 0782129110 */ /* Example12_2.cs illustrates the use of a multicast delegate */ using System; // declare the DelegateCalculation delegate class public delegate void DelegateCalculation( double acceleration, double time ); // declare the MotionCalculations class class MotionCalculations { // FinalSpeed() calculates the final speed public static void FinalSpeed( double acceleration, double time ) { double finalSpeed = acceleration * time; Console.WriteLine("finalSpeed = " + finalSpeed + " meters per second"); } // Distance() calculates the distance traveled public static void Distance( double acceleration, double time ) { double distance = acceleration * Math.Pow(time, 2) / 2; Console.WriteLine("distance = " + distance + " meters"); } } public class Example12_2 { public static void Main() { // declare and initialize the acceleration and time double acceleration = 10; // meters per second per second double time = 5; // seconds Console.WriteLine("acceleration = " + acceleration + " meters per second per second"); Console.WriteLine("time = " + time + " seconds"); // create delegate object that call the // MotionCalculations.FinalSpeed() and // MotionCalculations.Distance() methods DelegateCalculation myDelegateCalculation1 = new DelegateCalculation(MotionCalculations.FinalSpeed); DelegateCalculation myDelegateCalculation2 = new DelegateCalculation(MotionCalculations.Distance); // create a multicast delegate object from // myDelegateCalculation1 and // myDelegateCalculation2 DelegateCalculation myDelegateCalculations = myDelegateCalculation1 + myDelegateCalculation2; // calculate and display the final speed and distance // using myDelegateCalculations myDelegateCalculations(acceleration, time); } }
illustrates the use of a delegate 2
/* Mastering Visual C# .NET by Jason Price, Mike Gunderloy Publisher: Sybex; ISBN: 0782129110 */ /* Example12_1.cs illustrates the use of a delegate */ using System; // declare the DelegateCalculation delegate class public delegate double DelegateCalculation( double acceleration, double time ); // declare the MotionCalculations class class MotionCalculations { // FinalSpeed() calculates the final speed public static double FinalSpeed( double acceleration, double time ) { double finalSpeed = acceleration * time; return finalSpeed; } // Distance() calculates the distance traveled public static double Distance( double acceleration, double time ) { double distance = acceleration * Math.Pow(time, 2) / 2; return distance; } } public class Example12_1 { public static void Main() { // declare and initialize the acceleration and time double acceleration = 10; // meters per second per second double time = 5; // seconds Console.WriteLine("acceleration = " + acceleration + " meters per second per second"); Console.WriteLine("time = " + time + " seconds"); // create a delegate object that calls // MotionCalculations.FinalSpeed DelegateCalculation myDelegateCalculation = new DelegateCalculation(MotionCalculations.FinalSpeed); // calculate and display the final speed double finalSpeed = myDelegateCalculation(acceleration, time); Console.WriteLine("finalSpeed = " + finalSpeed + " meters per second"); // set the delegate method to MotionCalculations.Distance myDelegateCalculation = new DelegateCalculation(MotionCalculations.Distance); // calculate and display the distance traveled double distance = myDelegateCalculation(acceleration, time); Console.WriteLine("distance = " + distance + " meters"); } }
Late Binding Delegates: A delegate is a repository of type-safe function pointers.
using System; using System.Reflection; delegate void XDelegate(int arga, int argb); class MyClass { public void MethodA(int arga, int argb) { Console.WriteLine("MyClass.MethodA called: {0} {1}", arga, argb); } } class Starter { static void Main() { MyClass obj = new MyClass(); XDelegate delObj = new XDelegate(obj.MethodA); delObj.Invoke(1, 2); delObj(3, 4); } }
Define your own delegate
/* Learning C# by Jesse Liberty Publisher: O'Reilly ISBN: 0596003765 */ using System; namespace DelegatesAndEvents { class MyClassWithDelegate { // The delegate declaration. public delegate void StringDelegate(string s); } class MyImplementingClass { public static void WriteString(string s) { Console.WriteLine("Writing string {0}", s); } public static void LogString(string s) { Console.WriteLine("Logging string {0}", s); } public static void TransmitString(string s) { Console.WriteLine("Transmitting string {0}", s); } } public class TesterDelegatesAndEvents { public void Run() { // Define three StringDelegate objects. MyClassWithDelegate.StringDelegate Writer, Logger, Transmitter; // Define another StringDelegate // to act as the multicast delegate. MyClassWithDelegate.StringDelegate myMulticastDelegate; // Instantiate the first three delegates, // passing in methods to encapsulate. Writer = new MyClassWithDelegate.StringDelegate( MyImplementingClass.WriteString); Logger = new MyClassWithDelegate.StringDelegate( MyImplementingClass.LogString); Transmitter = new MyClassWithDelegate.StringDelegate( MyImplementingClass.TransmitString); // Invoke the Writer delegate method. Writer("String passed to Writer "); // Invoke the Logger delegate method. Logger("String passed to Logger "); // Invoke the Transmitter delegate method. Transmitter("String passed to Transmitter "); // Tell the user you are about to combine // two delegates into the multicast delegate. Console.WriteLine( "myMulticastDelegate = Writer + Logger"); // Combine the two delegates; assign the result // to myMulticastDelegate myMulticastDelegate = Writer + Logger; // Call the delegated methods; two methods // will be invoked. myMulticastDelegate( "First string passed to Collector"); // Tell the user you are about to add // a third delegate to the multicast. Console.WriteLine( " myMulticastDelegate += Transmitter"); // Add the third delegate. myMulticastDelegate += Transmitter; // Invoke the three delegated methods. myMulticastDelegate( "Second string passed to Collector"); // Tell the user you are about to remove // the Logger delegate. Console.WriteLine( " myMulticastDelegate -= Logger"); // Remove the Logger delegate. myMulticastDelegate -= Logger; // Invoke the two remaining delegated methods. myMulticastDelegate( "Third string passed to Collector"); } [STAThread] static void Main() { TesterDelegatesAndEvents t = new TesterDelegatesAndEvents(); t.Run(); } } }