Section A.17. Chapter 17: Delegates and Events


A.17. Chapter 17: Delegates and Events

A.17.1. Quiz



Solution to Question 171 .

The following is the standard way to define a delegate:

 public delegate void PhoneRangHandler ( object sender, EventArgs e ); public event PhoneRangHandler PhoneRang; 



Solution to Question 172 .

Reference types.



Solution to Question 173 .

To decouple the method(s) called from the calling code. It allows the designer of an object to define the delegate, and the user of the object to define which method will be called when the delegate is invoked.



Solution to Question 174 .

You instantiate a delegate like this:

 OnPhoneRings myDelegate = new OnPhoneRings(myMethod); 



Solution to Question 175 .

Here is how to call a delegated method:

 OnPhoneRings(object this, new EventArgs(  )); 



Solution to Question 176 .

The ability for more than one method to be called through a single delegate.



Solution to Question 177 .

Limits the use of the delegate in the following ways:

  • You can only add a method using += .

  • You can only remove a method using -= .

  • The delegate can only be invoked by the class that defines it.



Solution to Question 178 .

Define the delegate to take, as its second parameter, an object of a type derived from EventArgs . Pass the information through properties of that object.



Solution to Question 179 .

None.



Solution to Question 1710 .

Rather than creating a method that matches the delegate's signature and then assigning the name of that method to the delegate, you can directly assign an unnamed delegate method by providing the implementation in line with the assignment.

A.17.2. Exercises



Solution to Exercise 17-1 .

Write a countdown alarm program that uses delegates to notify anyone who is interested that the designated amount of time has passed:

 using System; using System.Collections.Generic; using System.Text; using System.Threading; namespace Exercise1 {    // a class to hold the message to display    public class CountDownClockEventArgs : EventArgs    {       public readonly string message;       public CountDownClockEventArgs( string message )       {          this.message = message;       }    }    // The subject (publisher). The class to which other    // classes will subscribe. Provides the delegate TimeExpired    // that fires when the requested amount of time has passed    public class CountDownClock    {       private DateTime startingTime;       private DateTime targetTime;       private string message;       // tell me the message to display, and how much time       //(hours, minutes seconds) to wait       public CountDownClock( string message, int hours, int mins, int seconds )       {          this.message = message;          startingTime = DateTime.Now;          TimeSpan duration = new TimeSpan( hours, mins, seconds );          targetTime = startingTime + duration;       }       // the delegate       public delegate void TimesUpEventHandler       (            object countDownClock,            CountDownClockEventArgs alarmInformation       );       // an instance of the delegate       public TimesUpEventHandler TimeExpired;       // Check 10 times a second to see if the time has elapsed       // if so, if anyone is listening, send then message       public void Run(  )       {          for ( ; ; )          {             // sleep 1/10 of a second             Thread.Sleep( 100 );  // milliseconds             // get the current time             System.DateTime rightNow = System.DateTime.Now;             if ( rightNow >= this.targetTime )             {                if ( TimeExpired != null )                {                   // Create the CountDownClockEventArgs to hold the message                   CountDownClockEventArgs e =                     new CountDownClockEventArgs( this.message );                   // fire the event                   TimeExpired( this, e );                   // stop the timer                   break;                }     // end if registered delegates             }        // end if time has passed          }           // end forever loop       }              // end run    }                 // end class    // an observer.    public class CountDownTimerDisplay    {       CountDownClock.TimesUpEventHandler myHandler;       public CountDownTimerDisplay(CountDownClock cdc)       {          myHandler = new CountDownClock.TimesUpEventHandler( TimeExpired );          // register the event handler and start the timer          cdc.TimeExpired += myHandler;       }       // Alert the user that the time has expired       public void TimeExpired( object theClock, CountDownClockEventArgs e )       {          Console.WriteLine( e.message );       }    }    // an observer.    public class CountDownTimerLog    {       CountDownClock.TimesUpEventHandler myHandler;       public CountDownTimerLog( CountDownClock cdc )       {          myHandler = new CountDownClock.TimesUpEventHandler( TimeExpired );          // register the event handler and start the timer          cdc.TimeExpired += myHandler;       }       // Alert the user that the time has expired       public void TimeExpired( object theClock, CountDownClockEventArgs e )       {          Console.WriteLine( "logging " + e.message );       }    }    public class Test    {       public static void Main(  )       {          Console.Write( "Message: " );          string message = Console.ReadLine(  );          // NB: You would of course create a more sophisticated interface to          // let the user set the correct amount of time. For now, we'll just          // ask for how many seconds to wait          Console.Write( "How many seconds?: " );          int seconds = Convert.ToInt32( Console.ReadLine(  ) );          CountDownClock cdc = new CountDownClock( message, 0, 0, seconds );          CountDownTimerDisplay display = new CountDownTimerDisplay( cdc );          CountDownTimerLog logger = new CountDownTimerLog (cdc);          cdc.Run(  );       }    } } 



Solution to Exercise 17-2 .

Break the program you write in Exercise 17-1 by assigning a new handler to the delegate (deleting the old!).

The only change is in the registration of the handler, using = rather than += :

 public class CountDownTimerLog {    CountDownClock.TimesUpEventHandler myHandler;    public CountDownTimerLog( CountDownClock cdc )    {       myHandler = new CountDownClock.TimesUpEventHandler( TimeExpired );       // register the event handler and start the timer  cdc.TimeExpired = myHandler  ;    }    // Alert the user that the time has expired    public void TimeExpired( object theClock, CountDownClockEventArgs e )    {       Console.WriteLine( "logging " + e.message );    } } 



Solution to Exercise 17-3 .

Fix the program you wrote in Exercise 17-1 by using the event keyword and test against changes you added in Exercise 17-2.

The only change is in the declaration of the instance of the delegate, adding the keyword event, which will make Exercise 17-2 fail at compile time. Repairing it from = to += will let it run as an event.

 // the delegate public delegate void TimesUpEventHandler (      object countDownClock,      CountDownClockEventArgs alarmInformation ); // an instance of the delegate public  event  TimesUpEventHandler TimeExpired; 



Learning C# 2005
Learning C# 2005: Get Started with C# 2.0 and .NET Programming (2nd Edition)
ISBN: 0596102097
EAN: 2147483647
Year: 2004
Pages: 250

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net