Csharp/C Sharp/Language Basics/delegate
Содержание
- 1 Arrays of Delegates
- 2 A simple delegate example
- 3 Combining delegates Multiple delegates are combined using the Combine method, the plus operator (+), or the += assignment operator.
- 4 CreateDelegate and DynamicInvoke
- 5 Define your own delegate
- 6 Delegates can refer to instance methods, too
- 7 Delegates:Multicasting
- 8 Delegates to Instance Members
- 9 Delegates:Using Delegates
- 10 Demonstrate getting and printing the invocation list for a delegate
- 11 Demonstrates adding multiple methods to a delegate
- 12 Demonstrates a simple form of a delegate
- 13 Demonstrates combining and removing delegates to create new delegates
- 14 Demonstrate using a static delegate without declaring an instance of the class
- 15 illustrates the use of a delegate 2
- 16 illustrates the use of a delegate that calls object methods
- 17 illustrates the use of a multicast delegate
- 18 Late Binding Delegates: A delegate is a repository of type-safe function pointers.
- 19 Lifetime of outer variables is aligned with the delegate
- 20 The minimum implementation of a delegate
- 21 The publisher/subscriber relationship is a one-to-many relationship.
- 22 the syntax of the GetInvocationList method: delegate [] GetInvocationList()
- 23 To remove delegates from a multicast delegate, use the Remove method, the minus operator (-), or the -= assignment operator.
- 24 Two delegates
- 25 Using a delegate with a container class o sort the collection and return a sorted array using different ort criteria
Arrays of Delegates
<source lang="csharp"> using System; public delegate void Task(); public class Starter {
public static void Main() { Task[] tasks = { MethodA, MethodB, MethodC }; string resp; tasks[0](); tasks[1](); tasks[2](); } public static void MethodA() { Console.WriteLine("Doing TaskA"); } public static void MethodB() { Console.WriteLine("Doing TaskB"); } public static void MethodC() { Console.WriteLine("Doing TaskC"); }
}
</source>
A simple delegate example
<source lang="csharp"> /* 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(" ", "-"); } // Remove spaces. static string removeSpaces(string a) { string temp = ""; int i; Console.WriteLine("Removing spaces."); for(i=0; i < a.Length; i++) if(a[i] != " ") temp += a[i]; 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); }
}
</source>
Combining delegates Multiple delegates are combined using the Combine method, the plus operator (+), or the += assignment operator.
<source lang="csharp"> using System; public delegate void DelegateClass(); public class Starter {
public static void Main() { DelegateClass del = MethodA; del += MethodB; del(); } public static void MethodA() { Console.WriteLine("MethodA..."); } public static void MethodB() { Console.WriteLine("MethodB..."); }
}
</source>
CreateDelegate and DynamicInvoke
<source lang="csharp"> using System; using System.Reflection; delegate void theDelegate(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() { Type tObj = typeof(System.MulticastDelegate); MyClass obj = new MyClass(); Delegate del = Delegate.CreateDelegate(typeof(theDelegate), obj,"MethodA"); del.DynamicInvoke(new object[] { 1, 2 }); }
}
</source>
Define your own delegate
<source lang="csharp"> /* 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\n"); // Invoke the Logger delegate method. Logger("String passed to Logger\n"); // Invoke the Transmitter delegate method. Transmitter("String passed to Transmitter\n"); // 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( "\nmyMulticastDelegate += 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( "\nmyMulticastDelegate -= 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(); } } } </source>
Delegates can refer to instance methods, too
<source lang="csharp"> /* 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[i] != " ") temp += a[i]; 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); }
}
</source>
Delegates:Multicasting
<source lang="csharp"> using System; public class DelegatesMulticasting {
delegate void ProcessHandler(string message); static public void Process(string message) { Console.WriteLine("Test.Process(\"{0}\")", message); } public static void Main() { User user = new User("George"); ProcessHandler ph = new ProcessHandler(user.Process); ph = (ProcessHandler) Delegate.rubine(ph, new ProcessHandler(Process)); ph("Wake Up!"); }
} public class User {
string name; public User(string name) { this.name = name; } public void Process(string message) { Console.WriteLine("{0}: {1}", name, message); }
}
</source>
Delegates to Instance Members
<source lang="csharp"> using System; public class DelegatestoInstanceMembers {
delegate void ProcessHandler(string message); public static void Main() { User aUser = new User("George"); ProcessHandler ph = new ProcessHandler(aUser.Process); ph("Wake Up!"); }
} public class User {
string name; public User(string name) { this.name = name; } public void Process(string message) { Console.WriteLine("{0}: {1}", name, message); }
}
</source>
Delegates:Using Delegates
<source lang="csharp"> /* A Programmer"s Introduction to C# (Second Edition) by Eric Gunnerson Publisher: Apress L.P. ISBN: 1-893115-62-3
- /
// 22 - Delegates\Using Delegates // copyright 2000 Eric Gunnerson using System;
public class DelegatesUsingDelegates {
public static void Main() { Container employees = new Container(); // create and add some employees here // create delegate to sort on names, and do the sort Container.rupareItemsCallback sortByName = new Container.rupareItemsCallback(Employee.rupareName); employees.Sort(sortByName); // employees is now sorted by name }
} public class Container {
public delegate int CompareItemsCallback(object obj1, object obj2); public void Sort(CompareItemsCallback compare) { // not a real sort, just shows what the // inner loop code might do int x = 0; int y = 1; object item1 = arr[x]; object item2 = arr[y]; int order = compare(item1, item2); } object[] arr = new object[1]; // items in the collection
} public class Employee {
Employee(string name, int id) { this.name = name; this.id = id; } public static int CompareName(object obj1, object obj2) { Employee emp1 = (Employee) obj1; Employee emp2 = (Employee) obj2; return(String.rupare(emp1.name, emp2.name)); } public static int CompareId(object obj1, object obj2) { Employee emp1 = (Employee) obj1; Employee emp2 = (Employee) obj2; if (emp1.id > emp2.id) return(1); if (emp1.id < emp2.id) return(-1); else return(0); } string name; int id;
}
</source>
Demonstrate getting and printing the invocation list for a delegate
<source lang="csharp"> /* C# Programming Tips & 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"); } }
}
</source>
Demonstrates adding multiple methods to a delegate
<source lang="csharp"> /* C# Programming Tips & 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"); } }
}
</source>
Demonstrates a simple form of a delegate
<source lang="csharp"> /* 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)); } }
}
</source>
Demonstrates combining and removing delegates to create new delegates
<source lang="csharp"> /* 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 ("\r\nExecuting 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 ("\r\nExecute 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); } }
}
</source>
Demonstrate using a static delegate without declaring an instance of the class
<source lang="csharp"> /* C# Programming Tips & 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; }
}
</source>
illustrates the use of a delegate 2
<source lang="csharp"> /* 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"); }
}
</source>
illustrates the use of a delegate that calls object methods
<source lang="csharp"> /* 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); }
}
</source>
illustrates the use of a multicast delegate
<source lang="csharp"> /* 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); }
}
</source>
Late Binding Delegates: A delegate is a repository of type-safe function pointers.
<source lang="csharp"> 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); }
}
</source>
Lifetime of outer variables is aligned with the delegate
<source lang="csharp"> using System; public delegate void DelegateClass(out int var); public class Starter {
public static void Main() { DelegateClass del = MethodA(); int var; del(out var); del(out var); del(out var); Console.WriteLine(var); } public static DelegateClass MethodA() { int increment = 0; return delegate(out int var) { var = ++increment; }; }
}
</source>
The minimum implementation of a delegate
<source lang="csharp"> /* C# Programming Tips & Techniques by Charles Wright, Kris Jamsa Publisher: Osborne/McGraw-Hill (December 28, 2001) ISBN: 0072193794
- /
// Delegate.cs - Demonstrates the minimum implementation of a delegate // Compile this program with the following command line: // C:>csc Delegate.cs // namespace nsDelegate {
using System; public class Delegate21 {
// Declare the delegate type
public delegate double MathHandler (double val);
// Declare the variable that will hold the delegate
public MathHandler DoMath; static public void Main () { double val = 31.2; double result; Delegate21 main = new Delegate21();
// Create the first delegate
main.DoMath = new Delegate21.MathHandler (main.Square);
// Call the function through the delegate
result = main.DoMath (val); Console.WriteLine ("The square of {0,0:F1} is {1,0:F3}", val, result);
// Create the second delegate
main.DoMath = new Delegate21.MathHandler (main.SquareRoot);
// Call the function through the delegate
result = main.DoMath (val); Console.WriteLine ("The square root of {0,0:F1} is {1,0:F3}", val, result); } public double Square (double val) { return (val * val); } public double SquareRoot (double val) { return (Math.Sqrt (val)); } }
}
</source>
The publisher/subscriber relationship is a one-to-many relationship.
<source lang="csharp"> using System; class Publisher {
public event EventHandler MyEvent;
} public class Subscriber {
public static void Handler(object obj, EventArgs args) { } public static void Main() { Publisher pub = new Publisher(); pub.MyEvent += Handler; // other processing }
}
</source>
the syntax of the GetInvocationList method: delegate [] GetInvocationList()
<source lang="csharp"> using System; public delegate void DelegateClass(); public class Starter {
public static void Main() { DelegateClass del = (DelegateClass) DelegateClass.rubine(new DelegateClass[] { MethodA, MethodB, MethodA, MethodB }); del(); foreach (DelegateClass item in del.GetInvocationList()) { Console.WriteLine(item.Method.Name + " in invocation list."); } } public static void MethodA() { Console.WriteLine("MethodA..."); } public static void MethodB() { Console.WriteLine("MethodB..."); }
}
</source>
To remove delegates from a multicast delegate, use the Remove method, the minus operator (-), or the -= assignment operator.
<source lang="csharp"> using System; public delegate void DelegateClass(); public class Starter {
public static void Main(){ DelegateClass del=MethodA; del+=MethodB; del+=MethodC; del=del-MethodB; del(); } public static void MethodA() { Console.WriteLine("MethodA..."); } public static void MethodB() { Console.WriteLine("MethodB..."); } public static void MethodC() { Console.WriteLine("MethodC..."); }
}
</source>
Two delegates
<source lang="csharp"> /*
* 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; } }
}
</source>
Using a delegate with a container class o sort the collection and return a sorted array using different ort criteria
<source lang="csharp"> /* C# Programming Tips & 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.ruponentModel; 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"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 ("\t" + emp); } // Sort the employees by last name and show the list. Console.WriteLine ("\r\nSorted by last name:"); clsEmployee [] arr = SortList (SortBy.Name); foreach (clsEmployee emp in arr) { Console.WriteLine ("\t" + emp); } // Sort the employees by ID number and show the list. Console.WriteLine ("\r\nSorted by employee ID:"); arr = SortList (SortBy.ID); foreach (clsEmployee emp in arr) { Console.WriteLine ("\t" + emp); } // Sort the employees by ZIP code and show the list. Console.WriteLine ("\r\nSorted by ZIP code:"); arr = SortList (SortBy.ZIP); foreach (clsEmployee emp in arr) { Console.WriteLine ("\t" + emp); } } // Define a method that will create the proper delegate according to // the sort that is needed. static clsEmployee [] SortList (SortBy iSort) { clsEmployeeContainer.rupareItems sort = null; switch (iSort) { case SortBy.Name: sort = new clsEmployeeContainer.rupareItems(clsEmployee.rupareByName); break; case SortBy.ID: sort = new clsEmployeeContainer.rupareItems(clsEmployee.rupareByID); break; case SortBy.ZIP: sort = new clsEmployeeContainer.rupareItems(clsEmployee.rupareByZip); 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"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.rupare (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.rupare (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.ruponents; // 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[x + 1], arrEmployee[x]); else result = sort (arrEmployee[x], arrEmployee[x + 1]); // 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.ruponents); } }
}
</source>