Csharp/C Sharp/Language Basics/delegate — различия между версиями
Admin (обсуждение | вклад) м (1 версия) |
Admin (обсуждение | вклад) м (1 версия) |
(нет различий)
|
Текущая версия на 11:39, 26 мая 2010
Содержание
- 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
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");
}
}
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(" ", "-");
}
// 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);
}
}
Combining delegates Multiple delegates are combined using the Combine method, the plus operator (+), or the += assignment operator.
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...");
}
}
CreateDelegate and DynamicInvoke
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 });
}
}
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\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();
}
}
}
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[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);
}
}
Delegates:Multicasting
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);
}
}
Delegates to Instance Members
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);
}
}
Delegates:Using Delegates
/*
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;
}
Demonstrate getting and printing the invocation list for a delegate
/*
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");
}
}
}
Demonstrates adding multiple methods to a delegate
/*
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");
}
}
}
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));
}
}
}
Demonstrates combining and removing delegates to create new delegates
/*
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);
}
}
}
Demonstrate using a static delegate without declaring an instance of the class
/*
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;
}
}
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");
}
}
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);
}
}
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);
}
}
Lifetime of outer variables is aligned with the delegate
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;
};
}
}
The minimum implementation of a delegate
/*
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));
}
}
}
The publisher/subscriber relationship is a one-to-many relationship.
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
}
}
the syntax of the GetInvocationList method: delegate [] GetInvocationList()
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...");
}
}
To remove delegates from a multicast delegate, use the Remove method, the minus operator (-), or the -= assignment operator.
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...");
}
}
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;
}
}
}
Using a delegate with a container class o sort the collection and return a sorted array using different ort criteria
/*
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);
}
}
}