listing 1 // A simple delegate example. using System; // Declare a delegate type. delegate string StrMod(string str); class DelegateTest { // Replaces spaces with hyphens. static string ReplaceSpaces(string s) { Console.WriteLine("Replacing spaces with hyphens."); return s.Replace(' ', '-'); } // Remove spaces. static string RemoveSpaces(string s) { string temp = ""; int i; Console.WriteLine("Removing spaces."); for(i=0; i < s.Length; i++) if(s[i] != ' ') temp += s[i]; return temp; } // Reverse a string. static string Reverse(string s) { string temp = ""; int i, j; Console.WriteLine("Reversing string."); for(j=0, i=s.Length-1; i >= 0; i--, j++) temp += s[i]; return temp; } 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); } } listing 2 static void Main() { // Construct a delegate using method group conversion. StrMod strOp = ReplaceSpaces; // use method group conversion string str; // Call methods through the delegate. str = strOp("This is a test."); Console.WriteLine("Resulting string: " + str); Console.WriteLine(); strOp = RemoveSpaces; // use method group conversion str = strOp("This is a test."); Console.WriteLine("Resulting string: " + str); Console.WriteLine(); strOp = Reverse; // use method group converison str = strOp("This is a test."); Console.WriteLine("Resulting string: " + str); } listing 3 // Delegates can refer to instance methods, too. using System; // Declare a delegate type. delegate string StrMod(string str); class StringOps { // Replaces spaces with hyphens. public string ReplaceSpaces(string s) { Console.WriteLine("Replacing spaces with hyphens."); return s.Replace(' ', '-'); } // Remove spaces. public string RemoveSpaces(string s) { string temp = ""; int i; Console.WriteLine("Removing spaces."); for(i=0; i < s.Length; i++) if(s[i] != ' ') temp += s[i]; return temp; } // Reverse a string. public string Reverse(string s) { string temp = ""; int i, j; Console.WriteLine("Reversing string."); for(j=0, i=s.Length-1; i >= 0; i--, j++) temp += s[i]; return temp; } } class DelegateTest { static void Main() { StringOps so = new StringOps(); // create an instance of StringOps // Initialize a delegate. StrMod strOp = so.ReplaceSpaces; string str; // Call methods through delegates. str = strOp("This is a test."); Console.WriteLine("Resulting string: " + str); Console.WriteLine(); strOp = so.RemoveSpaces; str = strOp("This is a test."); Console.WriteLine("Resulting string: " + str); Console.WriteLine(); strOp = so.Reverse; str = strOp("This is a test."); Console.WriteLine("Resulting string: " + str); } } listing 4 // Demonstrate multicasting. using System; // Declare a delegate type. delegate void StrMod(ref string str); class MultiCastDemo { // Replaces spaces with hyphens. static void ReplaceSpaces(ref string s) { Console.WriteLine("Replacing spaces with hyphens."); s = s.Replace(' ', '-'); } // Remove spaces. static void RemoveSpaces(ref string s) { string temp = ""; int i; Console.WriteLine("Removing spaces."); for(i=0; i < s.Length; i++) if(s[i] != ' ') temp += s[i]; s = temp; } // Reverse a string. static void Reverse(ref string s) { string temp = ""; int i, j; Console.WriteLine("Reversing string."); for(j=0, i=s.Length-1; i >= 0; i--, j++) temp += s[i]; s = temp; } static void Main() { // Construct delegates. StrMod strOp; StrMod replaceSp = ReplaceSpaces; StrMod removeSp = RemoveSpaces; StrMod reverseStr = Reverse; string str = "This is a test"; // Set up multicast. strOp = replaceSp; strOp += reverseStr; // Call multicast. strOp(ref str); Console.WriteLine("Resulting string: " + str); Console.WriteLine(); // Remove replace and add remove. strOp -= replaceSp; strOp += removeSp; str = "This is a test."; // reset string // Call multicast. strOp(ref str); Console.WriteLine("Resulting string: " + str); Console.WriteLine(); } } listing 13 // A very simple event demonstration. using System; // Declare a delegate type for an event. delegate void MyEventHandler(); // Declare a class that contains an event. class MyEvent { public event MyEventHandler SomeEvent; // This is called to raise the event. public void OnSomeEvent() { if(SomeEvent != null) SomeEvent(); } } class EventDemo { // An event handler. static void Handler() { Console.WriteLine("Event occurred"); } static void Main() { MyEvent evt = new MyEvent(); // Add Handler() to the event list. evt.SomeEvent += Handler; // Raise the event. evt.OnSomeEvent(); } } listing 14 // An event multicast demonstration. using System; // Declare a delegate type for an event. delegate void MyEventHandler(); // Declare a class that contains an event. class MyEvent { public event MyEventHandler SomeEvent; // This is called to raise the event. public void OnSomeEvent() { if(SomeEvent != null) SomeEvent(); } } class X { public void Xhandler() { Console.WriteLine("Event received by X object"); } } class Y { public void Yhandler() { Console.WriteLine("Event received by Y object"); } } class EventDemo2 { static void Handler() { Console.WriteLine("Event received by EventDemo"); } static void Main() { MyEvent evt = new MyEvent(); X xOb = new X(); Y yOb = new Y(); // Add handlers to the event list. evt.SomeEvent += Handler; evt.SomeEvent += xOb.Xhandler; evt.SomeEvent += yOb.Yhandler; // Raise the event. evt.OnSomeEvent(); Console.WriteLine(); // Remove a handler. evt.SomeEvent -= xOb.Xhandler; evt.OnSomeEvent(); } } listing 15 /* Individual objects receive notifications when instance event handlers are used. */ using System; // Declare a delegate type for an event. delegate void MyEventHandler(); // Declare a class that contains an event. class MyEvent { public event MyEventHandler SomeEvent; // This is called to raise the event. public void OnSomeEvent() { if(SomeEvent != null) SomeEvent(); } } class X { int id; public X(int x) { id = x; } // This is an instance method that will be used as an event handler. public void Xhandler() { Console.WriteLine("Event received by object " + id); } } class EventDemo3 { static void Main() { MyEvent evt = new MyEvent(); X o1 = new X(1); X o2 = new X(2); X o3 = new X(3); evt.SomeEvent += o1.Xhandler; evt.SomeEvent += o2.Xhandler; evt.SomeEvent += o3.Xhandler; // Raise the event. evt.OnSomeEvent(); } } listing 16 /* A class receives the notification when a static method is used as an event handler. */ using System; // Declare a delegate type for an event. delegate void MyEventHandler(); // Declare a class that contains an event. class MyEvent { public event MyEventHandler SomeEvent; // This is called to raise the event. public void OnSomeEvent() { if(SomeEvent != null) SomeEvent(); } } class X { /* This is a static method that will be used as an event handler. */ public static void Xhandler() { Console.WriteLine("Event received by class."); } } class EventDemo4 { static void Main() { MyEvent evt = new MyEvent(); evt.SomeEvent += X.Xhandler; // Raise the event. evt.OnSomeEvent(); } } listing 17 // Create a custom means of managing the event invocation list. using System; // Declare a delegate type for an event. delegate void MyEventHandler(); // Declare a class that holds up to 3 events. class MyEvent { MyEventHandler[] evnt = new MyEventHandler[3]; public event MyEventHandler SomeEvent { // Add an event to the list. add { int i; for(i=0; i < 3; i++) if(evnt[i] == null) { evnt[i] = value; break; } if (i == 3) Console.WriteLine("Event list full."); } // Remove an event from the list. remove { int i; for(i=0; i < 3; i++) if(evnt[i] == value) { evnt[i] = null; break; } if (i == 3) Console.WriteLine("Event handler not found."); } } // This is called to raise the events. public void OnSomeEvent() { for(int i=0; i < 3; i++) if(evnt[i] != null) evnt[i](); } } // Create some classes that use MyEventHandler. class W { public void Whandler() { Console.WriteLine("Event received by W object"); } } class X { public void Xhandler() { Console.WriteLine("Event received by X object"); } } class Y { public void Yhandler() { Console.WriteLine("Event received by Y object"); } } class Z { public void Zhandler() { Console.WriteLine("Event received by Z object"); } } class EventDemo5 { static void Main() { MyEvent evt = new MyEvent(); W wOb = new W(); X xOb = new X(); Y yOb = new Y(); Z zOb = new Z(); // Add handlers to the event list. Console.WriteLine("Adding events."); evt.SomeEvent += wOb.Whandler; evt.SomeEvent += xOb.Xhandler; evt.SomeEvent += yOb.Yhandler; // Can't store this one -- full. evt.SomeEvent += zOb.Zhandler; Console.WriteLine(); // Raise the events. evt.OnSomeEvent(); Console.WriteLine(); // Remove a handler. Console.WriteLine("Remove xOb.Xhandler."); evt.SomeEvent -= xOb.Xhandler; evt.OnSomeEvent(); Console.WriteLine(); // Try to remove it again. Console.WriteLine("Try to remove xOb.Xhandler again."); evt.SomeEvent -= xOb.Xhandler; evt.OnSomeEvent(); Console.WriteLine(); // Now, add Zhandler. Console.WriteLine("Add zOb.Zhandler."); evt.SomeEvent += zOb.Zhandler; evt.OnSomeEvent(); } } listing 19 // A .NET-compatible event. using System; // Derive a class from EventArgs. class MyEventArgs : EventArgs { public int EventNum; } // Declare a delegate type for an event. delegate void MyEventHandler(object sender, MyEventArgs e); // Declare a class that contains an event. class MyEvent { static int count = 0; public event MyEventHandler SomeEvent; // This raises SomeEvent. public void OnSomeEvent() { MyEventArgs arg = new MyEventArgs(); if(SomeEvent != null) { arg.EventNum = count++; SomeEvent(this, arg); } } } class X { public void Handler(object sender, MyEventArgs e) { Console.WriteLine("Event " + e.EventNum + " received by an X object."); Console.WriteLine("Source is " + sender); Console.WriteLine(); } } class Y { public void Handler(object sender, MyEventArgs e) { Console.WriteLine("Event " + e.EventNum + " received by a Y object."); Console.WriteLine("Source is " + sender); Console.WriteLine(); } } class EventDemo6 { static void Main() { X ob1 = new X(); Y ob2 = new Y(); MyEvent evt = new MyEvent(); // Add Handler() to the event list. evt.SomeEvent += ob1.Handler; evt.SomeEvent += ob2.Handler; // Raise the event. evt.OnSomeEvent(); evt.OnSomeEvent(); } } listing 20 // Use the built-in EventHandler delegate. using System; // Declare a class that contains an event. class MyEvent { public event EventHandler SomeEvent; // uses EventHandler delegate // This is called to raise SomeEvent. public void OnSomeEvent() { if(SomeEvent != null) SomeEvent(this, EventArgs.Empty); } } class EventDemo7 { static void Handler(object sender, EventArgs e) { Console.WriteLine("Event occurred"); Console.WriteLine("Source is " + sender); } static void Main() { MyEvent evt = new MyEvent(); // Add Handler() to the event list. evt.SomeEvent += Handler; // Raise the event. evt.OnSomeEvent(); } } listing 21 // A keypress event example. using System; // Derive a custom EventArgs class that holds the key. class KeyEventArgs : EventArgs { public char ch; } // Declare a keypress event class. class KeyEvent { public event EventHandler KeyPress; // This is called when a key is pressed. public void OnKeyPress(char key) { KeyEventArgs k = new KeyEventArgs(); if(KeyPress != null) { k.ch = key; KeyPress(this, k); } } } // Demonstrate KeyEvent. class KeyEventDemo { static void Main() { KeyEvent kevt = new KeyEvent(); ConsoleKeyInfo key; int count = 0; // Use a lambda expression to display the keypress. kevt.KeyPress += (sender, e) => Console.WriteLine(" Received keystroke: " + e.ch); // Use a lambda expression to count keypresses. kevt.KeyPress += (sender, e) => count++; // count is an outer variable Console.WriteLine("Enter some characters. " + "Enter a period to stop."); do { key = Console.ReadKey(); kevt.OnKeyPress(key.KeyChar); } while(key.KeyChar != '.'); Console.WriteLine(count + " keys pressed."); } }