Answers to Chapter 20 Review Questions


Chapter 20


What are the similarities and differences between delegates and abstract methods?



  • They both specify a return type and parameters for a method that they are able to represent and invoke at runtime.

  • They both allow you to postpone the decision of which method to invoke until runtime.


  • The method name must match that of the abstract class. The method name is irrelevant for the delegate.

  • Abstract methods work through inheritance, interfaces, and dynamic binding.

  • Generally, delegates are more suited for event handling purposes.


Why is delegate a good name for the delegate construct?


A delegate is called like a method, but unlike the method, it does not execute the call itself. Instead, it delegates the execution to the method it encapsulates at the time the delegate is called.


Where in a program can a delegate definition be positioned?


A delegate is just another class, so a delegate definition can be positioned in the same location as a class definition.


Consider the following delegate definition:

 public delegate int Filtering(string str); 

Which of the following methods can instances of this delegate encapsulate?

  1. protected int Filtering(string myString, double x) {...}

  2. internal static int FilteringOp(string myStr) {...}

  3. public double Filtering(string str) {...}

  4. public short Sum(int x, int y) {...}




Why must multicast delegates have the return type void?


A multicast delegate can encapsulate several methods. If the multicast delegate specified a return type other than void, the methods it encapsulates would all return a value. It is impossible to specify how these return values should be processed.

  1. Which arithmetic operators can be used with multicast delegates?

  2. Which arithmetic operators can be used with events when called from outside the object where they reside?

  1. +, -, +=, -=

  2. +=, -=


What is an event handler?


An event handler is a method that resides in the subscribing object. When the event (that this event handler is handling) is fired in the publisher, the event handler is invoked.

Answers to Chapter 20 Programming Exercises


Add a static method called Product to the Math class in Listing 20.1. This method must calculate the product of two parameters and be encapsulated by instances of the Calculation delegate. Write the code for testing this method with the delegate.


Exercise 1: Insert the following method in the Math class:

 public static double Product(int number1, int number2) {     return (number1 * number2); } 

To test this method, insert the following lines in the Main method:

 myCalculation = new Calculation(Math.Product); result = myCalculation(10, 20); Console.WriteLine("Result of passing 10, 20 to myCalculation: {0}", result); 

Write a program similar to Listing 20.2. This time, instead of letting a number be manipulated by three different math operations, let the program allow an initial single letter to be manipulated by the three following string operations: "Add an 'A' to the string", "Add a B to the string", and "Add a C to the string". Allow the user to put together any sequence of string operations with a maximum of twenty operations.


Exercise 2:

 using System; delegate string DoStringProcessing(string text); class CharacterProcessor {     private DoStringProcessing[] processingList;     private int stringProcessingCounter;     public CharacterProcessor()     {         stringProcessingCounter = 0;         processingList = new DoStringProcessing[20];     }     public void AddStringOperation(DoStringProcessing newStringProcess)     {         processingList[stringProcessingCounter] = newStringProcess;         stringProcessingCounter++;     }     public string StartProcessing(string tempString)     {         Console.WriteLine("Start string: " + tempString);         for (int i = 0; i < stringProcessingCounter; i++)         {             tempString = processingList[i](tempString);         }         return tempString;     } } class StringOperator {     public static DoStringProcessing DoAddA = new DoStringProcessing(AddA);     public static DoStringProcessing DoAddB = new DoStringProcessing(AddB);     public static DoStringProcessing DoAddC = new DoStringProcessing(AddC);     public static string AddA(string text)     {         Console.WriteLine("Add A to string");         return text + "A";     }     public static string AddB(string text)     {         Console.WriteLine("Add B to string");         return text + "B";     }     public static string AddC(string text)     {         Console.WriteLine("Add C to string");         return text + "C";     } } public class Tester {     public static void Main()     {         string startText;         string endResult;         string response;         CharacterProcessor processor = new CharacterProcessor();         Console.Write("Enter start string: ");         startText = Console.ReadLine();         Console.WriteLine("Create sequence of operations by repeatedly");         Console.WriteLine("choosing from the following options");         Console.WriteLine("A) Add A");         Console.WriteLine("B) Add B");         Console.WriteLine("C) Add C");         Console.WriteLine("When you wish to perform the processing enter P\n");         do         {             response = Console.ReadLine().ToUpper();             switch(response)             {                 case "A":                     processor.AddStringOperation(StringOperator.DoAddA);                     Console.WriteLine("Add A operation added");                 break;                 case "B":                     processor.AddStringOperation(StringOperator.DoAddB);                     Console.WriteLine("Add B operation added");                 break;                 case "C":                     processor.AddStringOperation(StringOperator.DoAddC);                     Console.WriteLine("Add C operation added");                 break;                 case "P":                     endResult = processor.StartProcessing(startText);                     Console.WriteLine("End result: {0}", endResult);                 break;                 default:                     Console.WriteLine("Invalid choice please try again");                 break;             }         }  while (response != "P");     } } 

Expand Listing 20.4 with another subscriber class called Motorbike. Allow Motorbike objects to subscribe to the events fired by the GameController object by equipping it with a suitable event handler and so forth, similar to the Car class. Program the event handler so that when one of the signals MoveRequestType.FastForward or MoveRequestType.SlowForward are received, the Motorbike object moves forward by 30. If the MoveRequestType.Reverse is received, reverse the Motorbike object by 3 kilometers. Allow the user to add and remove Motorbike objects similar to that of the Car objects.


Exercise 3: The enum MoveRequestType, the MoveRequestEventArgs class, the Car class, and the Tester class all remain unchanged and have not been displayed here. You can merely paste them in from Listing 20.4 to run the program.

 using System; class GameController {     public delegate void MoveRequest(object sender, MoveRequestEventArgs e);     public event MoveRequest OnMoveRequest;     Car[] gameCars = new Car[10];     Motorbike[] gameMotorbikes = new Motorbike[10];     string name;     int speedParam = 0;     int motorbikeCounter = 0;     int carCounter = 0;     int carNumber = 0;     int motorbikeNumber = 0;     public void Run()     {         string answer;         Console.WriteLine("Please select from the following menu: ");         Console.WriteLine("A)dd new car");         Console.WriteLine("B) Add new motorbike");         Console.WriteLine("C) Subscribe car to events");         Console.WriteLine("M) Subscribe motorbike to events");         Console.WriteLine("U)nsubscribe car from events");         Console.WriteLine("V) Unsubscribe motorbike from events");         Console.WriteLine("L)ist cars and motorbikes in current game");         Console.WriteLine("F)ast forward");         Console.WriteLine("S)low forward");         Console.WriteLine("R)everse");         Console.WriteLine("T)erminate");         do         {             Console.WriteLine("Select new option:");             answer = Console.ReadLine().ToUpper();             switch(answer)             {                 case "A":                     Console.Write("Enter name of the new car: ");                     name = Console.ReadLine();                     Console.Write("Enter car speed parameter of the new car: ");                     speedParam = Convert.ToInt32(Console.ReadLine());                     gameCars[carCounter] = new Car(speedParam, name);                     carCounter++;                 break;                 case "B":                     Console.Write("Enter name of the new motorbike: ");                     name = Console.ReadLine();                     gameMotorbikes[motorbikeCounter] = new Motorbike(name);                     motorbikeCounter++;                 break;                 case "C":                     Console.Write("Enter array index of car you want to [sr] subscribe to  graphics/ccc.gifevents: ");                     carNumber = Convert.ToInt32(Console.ReadLine());                     gameCars[carNumber].Subscribe(this);                 break;                 case "M":                     Console.Write("Enter array index of motorbike you want to subscribe  graphics/ccc.gifto events: ");                     motorbikeNumber = Convert.ToInt32(Console.ReadLine());                     gameMotorbikes[motorbikeNumber].Subscribe(this);                 break;                 case "U":                     Console.Write("Enter array index of car you want to                     unsubscribe from events: "); carNumber =  graphics/ccc.gifConvert.ToInt32(Console.ReadLine());                     gameCars[carNumber].Unsubscribe(this);                 break;                 case "V":                     Console.Write("Enter array index of motorbike you want to unsubscribe  graphics/ccc.giffrom events: ");                     motorbikeNumber = Convert.ToInt32(Console.ReadLine());                     gameMotorbikes[motorbikeNumber].Unsubscribe(this);                 break;                 case "L":                     Console.WriteLine("Cars currently listed:");                     for(int i=0; i < carCounter; i++)                     {                         Console.WriteLine(gameCars[i]);                     }                     Console.WriteLine("Motorbikes currently listed:");                     for(int i=0; i < motorbikeCounter; i++)                     {                         Console.WriteLine(gameMotorbikes[i]);                     }                 break;                 case "F":                     if (OnMoveRequest != null)                         OnMoveRequest(this, new MoveRequestEventArgs  graphics/ccc.gif(MoveRequestType.FastForward));                 break;                 case "S":                     if (OnMoveRequest != null)                         OnMoveRequest(this, new MoveRequestEventArgs  graphics/ccc.gif(MoveRequestType.SlowForward));                 break;                 case "R":                     if (OnMoveRequest != null)                         OnMoveRequest(this, new MoveRequestEventArgs  graphics/ccc.gif(MoveRequestType.Reverse));                 break;                 case "T":                 break;                 default:                     Console.WriteLine("Invalid choice. Please try again");                 break;             }         }  while(answer != "T");     } } class Motorbike {     private int distance;     private string name;     const int speedParam = 30;     public Motorbike(string initName)     {         distance = 0;         name = initName;     }     public void Subscribe(GameController controller)     {         controller.OnMoveRequest += new GameController.MoveRequest (MoveRequestHandler);     }     public void Unsubscribe(GameController controller)     {         controller.OnMoveRequest -= new GameController.MoveRequest (MoveRequestHandler);     }     public void MoveRequestHandler(object sender, MoveRequestEventArgs e)     {         switch (e.Request)         {             case MoveRequestType.SlowForward:                 distance += speedParam;                 Console.WriteLine("Motorbike name: " + name + " Moving forward. Distance:  graphics/ccc.gif" + distance);             break;             case MoveRequestType.FastForward:                 distance += speedParam;                 Console.WriteLine("Motorbike name: " + name + " Moving forward. Distance:  graphics/ccc.gif" + distance);             break;             case MoveRequestType.Reverse:                 distance -= 3;                 Console.WriteLine("Motorbike name: " + name + " Reversing. Distance: " +  graphics/ccc.gifdistance);             break;         }     }     public override string ToString()     {         return name;     } } 


C# Primer Plus
C Primer Plus (5th Edition)
ISBN: 0672326965
EAN: 2147483647
Year: 2000
Pages: 286
Authors: Stephen Prata

Similar book on Amazon © 2008-2017.
If you may any questions please contact us: