Consider the following example of delegate declaration: public delegate void MyDelegate string s; In the preceding example, the declared delegate type can be used to reference any metho
Trang 1Classes are reference types that allow you to create
instances of objects and use them in special ways to
meet your application’s requirement Another
reference type in C# is delegate Delegates allow
you to change the reference to a method at runtime
This means that you can decide the execution of a
method at run-time, based on the requirements of
your application
The method can be activated at the occurrence of an event, where an event is associated with the delegate
to call the method at run-time
This chapter discusses the creation of delegates
This chapter also discusses how to implement
multicast delegates In addition, it discusses how
you can use events with delegates
In this chapter, you will learn to:
Implement delegates
Implement multicast delegates
Use events with delegates
Objectives
Trang 3Delegates in C# allow you to dynamically change the reference to the methods in a class Consider an example of a coffee vending machine, which dispenses different flavors of coffee, such as cappuccino and black coffee On selecting the desired flavor of coffee, the vending machine decides to dispense the ingredients, such as milk powder, coffee
powder, hot water, cappuccino coffee powder All the materials are placed in different containers inside the vending machine The required material is dispensed when you select a flavor
Suppose, you select black coffee, the vending machine will call methods to dispense hot water and coffee powder only The reference to these methods is made dynamically, when you press the required button to dispense black coffee
A delegate is a reference type variable, which holds the reference to a method This
reference can be changed at runtime, as desired Although, delegates are a
general-purpose mechanism for indirectly calling methods at runtime, their primary use in C# programming is for implementing events and the call-back methods
To implement delegates in your application you need to declare delegates, instantiate delegates and use delegates
The methods that can be referenced by a delegate are determined by the delegate
declaration The delegate can refer to the methods, which have the same signature as that
of the delegate
Consider the following example of delegate declaration:
public delegate void MyDelegate (string s);
In the preceding example, the declared delegate type can be used to reference any method This method should have a single parameter of string type and it does not return any value
The following syntax is used for delegate declaration:
delegate <return type><delegate-name><parameter list>
Introducing Delegates
Declaring Delegates
Trang 4Create the delegate object of the delegate type, which you have already created Assign the address of the required method to the delegate object This can be done by calling the constructor of the delegate class and passing the method name The following example shows how to assign the address of a method to a delegate variable:
public void DelegateFunction(string PassValue)
{
// Method implementation Here
}
//Delegate Declaration
public delegate void MyDelegate(string ArgValue);
public void UseMethod()
MyDelegate The address of the DelegateFunction is assigned to the DelegateObject
by passing, the name of the function to the delegate constructor
You can call the delegate by giving the name of the delegate and by passing parameters, if required Using delegates is similar to calling methods
Consider a situation where you need to print information to a file and a screen There is some common information that needs to go to the file and to the screen There is also some specific information for both The methods to print the information to the file and screen are different You can call these methods at runtime by passing the common information
The following example shows how to use a delegate:
// This code is to print data to the output device, which is either a file or a screen
Trang 5//Creating the variables of Stream classes static FileStream FStream;
static StreamWriter SWriter;
//Defining a Delegate public delegate void PrintData(String s);
//Method to print a string to the console public static void WriteConsole (string str)
//Initializing stream objects
FStream = new FileStream("c:\\StoreData.txt", FileMode.Append, FileAccess.Write);
SWriter = new StreamWriter(FStream);
//Method to send the string data to respective methods
public static void DisplayData(PrintData PMethod) {
PMethod("This should go to the");
PrintData Fl = new PrintData (WriteFile);
//Invoking the DisplayData method with the Delegate object as the argument
Delegates are of two types and depending upon the requirement of the application the suitable type of delegate is selected
Trang 6There are two types of delegates, Single-cast delegate and Multicast delegate A
Single-cast delegate can call only one method at a time, whereas a Multicast delegate can call multiple methods at the same time
Single-Cast Delegate
A single-cast delegate derives from the System.Delegate class It contains reference to one method only at a time In the preceding example, the delegate used is a single-cast delegate The WriteConsole() and WriteFile() methods are being referenced by the delegate, PrintData, one after the other, at runtime
Consider the coffee vending machine example To provide black coffee a delegate that holds the reference to the methods to dispense hot water and coffee powder is used The reference to these methods is made dynamically, but one after the other This means coffee powder and hot water will be dispensed from the machine serially
Multicast Delegate
A multicast delegate derives from the System.MulticastDelegate class It contains an invocation list of multiple methods In multicasting you create a single delegate that invokes multiple encapsulated methods You need to ensure the return type of all these delegates is same
Consider the coffee vending machine example You are dispensing black coffee, which in turn calls the methods to dispense hot water and coffee powder If you want the methods
to dispense hot water and coffee powder to be called at the same time, you can make use
Consider the preceding example of printing a message to a file and to a screen in which the WriteFile() and WriteConsole() methods are called by using a single-cast delegate This example considers a situation where all the methods are called at the same instance Using the same delegate, multicasting helps to call both the WriteFile() method and the
WriteConsole() method in one call
The following code shows how to use a multicast delegate:
Types of Delegates
Trang 7//Method to print a string to the console public static void WriteConsole (String str) {
Console.WriteLine("{0} Console",str);
}
//Method to print a string to a file public static void WriteFile (String s) {
//Initializing stream objects
FStream = new FileStream("c:\\StoreData.txt", FileMode.Append, FileAccess.Write);
SWriter = new StreamWriter(FStream);
PMethod("This should go to the");
Trang 8Just a minute:
In the preceding example, the multicast delegate, MlDelegate holds reference of both the
WriteConsole() and WriteFile() methods
State whether the following statement is True or False:
Multicast delegates inherit from the System.Delegate.MulticastDelegate
class
Answer:
False
Trang 9An event is an action or occurrence, such as clicks, key presses, mouse movements, or
system generated notifications Applications can respond to events when they occur An example of a notification is interrupts Events are messages sent by the object to indicate the occurrence of the event Events are an effective mean of inter-process communication They are useful for an object because they provide signal state changes, which may be valuable to a client of the object
Consider an example of an event and the response to the event A clock is an object that shows 6 AM time and generates an event in the form of an alarm You accept the alarm event and act accordingly
The following figure shows the alarm event and handling of the event
Alarm Event and its Handling
Working with Events
Trang 10The following figure is the generalized representation that explains events and event handling
Events and Event Handling
In C#, delegates are used with events to implement event handling The NET Framework event model uses delegates to bind event notifications with methods known as event handlers When an event is generated, the delegate calls the associated event handler
The events are declared and raised in a class and associated with the event handlers using delegates within the same class or other classes Events are part of a class and the same class is used to publish its events The other classes can, however, accept these events or
in other words can subscribe to these events Events use the publisher and subscriber model
A publisher is an object that contains the definition of the event and the delegate The association of the event with the delegate is also specified in the publisher class The object of the publisher class invokes the event, which is notified to the other objects
Using Delegates with Events
Trang 11A subscriber is an object that wants to accept the event and provide a handler to the event The delegate of the publisher class invokes the method of the subscriber class This method in the subscriber class is the event handler The publisher and subscriber model implementation can be defined by the same class
The following figure shows the mechanism used by the publisher and subscriber objects
Publisher and Subscriber Objects
The implementation of an event includes events definition, events subscription and events notification
Defining an Event
The definition of the event in a publisher class includes the declaration of the delegate as well as the declaration of the event based on the delegate The following code defines a delegate named TimeToRise and an event named RingAlarm, which invokes the
TimeToRise delegate when it is raised:
public delegate void TimeToRise();
private event TimeToRise RingAlarm;
Trang 12Note
Subscribing to an Event
The event of the publisher class needs to be associated with its handler The event handler method is associated with the event using the delegate When the publisher object raises the event, the subscribing object associates the method, which needs to be called
Consider a class named Student which contains a method named WakeUp() The
requirement states that the method WakeUp() should be called at 6 AM The requirement could be implemented using events The following code shows how the Student class subscribes to the event named TimeToRise:
Student PD= new Student();
RingAlarm = new TimeToRise(PD.WakeUp);
The delegates that subscribe to an event must be declared void
Notifying Subscribers to an Event
The subscriber object notifies the subscriber object to the publisher object The event is raised to notify the handler
In the RingAlarm example, you do not require the WakeUp() method to be executed through the delegate because the event takes care of execution Write this block of code at
a place from where you want to notify the event to the subscribers of the event:
if (RingAlarm != null) {
RingAlarm( );
}
The preceding code block invokes all the associated delegates In this example, the
WakeUp() method that subscribes to the event is activated Notice, code checks if the event has at least one subscribing delegate Without this check, code throws an exception
if there are no subscribers
Trang 13The methods that subscribe an event might expect some input to be passed The event class can have these inputs at runtime on which the subscribing method works You need
to define the class that will pass the input to the event
Derive this class from System.EventArgs To pass values to a subscribing method, you need to enclose the parameters in a single class The single class supplies a special
method called the accessor method to retrieve the value This method is used to examine
or modify the members of a class Variables declared private are accessed indirectly through these methods
In the preceding RingAlarm example, the WakeUp() method needs to get information about time so that it can work Therefore, you create the class to pass the information about time to the subscriber through the event
The following code passes the information about time to the subscriber through the event:
public class TimeInfoEventArgs : EventArgs
{
private int Hour;
private int Minute;
private int Second;
public TimeInfoEventArgs( int Hour, int Minute, int Second) {
Trang 14Help the company to design an application for logging attendance
Solution
To design the application, you need to perform the following tasks:
1 Identify the technique that you will use in the application This technique will allow you to call the respective methods dynamically to log the attendance entry
2 Create a console-based application to implement the attendance log of workers
3 Compile and execute the application
Task 1: Identify the technique that you will use in the application This technique will allow you to call the respective methods dynamically to log the attendance entry
To demonstrate the working of the Attendance Log Entry application, various methods are required to be called dynamically You can use a delegate to call methods
dynamically You need to keep in mind that in the future the company may start new shifts The attendance entry can be treated as an event That event delegates attendance logging of workers to methods
Task 2: Creating a Console-Based Application
To create a console-based attendance logging application, you need to perform the
following steps:
1 Select StartÆAll ProgramsÆMicrosoft Visual Studio 2005ÆMicrosoft Visual
Studio 2005 The Start Page - Microsoft Visual Studio window is displayed
2 Select FileÆNewÆProject The New Project window is displayed
3 Select the project type as Visual C# from the Project types pane and Console
Application from the Templates pane
4 Type the name of the new project as AttendanceApp in the Name text box.
Activity: Attendance Log
Trang 155 Specify the location where the new project is to be created as
c:\Chapter12\Activity1 in the Location combo box
6 Click the OK button
7 Open the Solution Explorer window and right-click the Program.cs file The
shortcut menu is displayed
8 Select the Rename option and type the new name as DelegateEvent.cs.
9 Double-click the DelegateEvent.cs file in the Solution Explorer window The Code view of DelegateEvent.cs file is displayed
10 Replace the existing code with the following code:
public event AttendanceLogHandler EventLog;
// Instead of having the LogProcess() function take a
delegate
// as a parameter, we've declared a EventLog event
public void LogProcess()
{
string Reason = null;
Console.WriteLine("Enter your name");
string UserName = Console.ReadLine();
DateTime t = DateTime.Now;
int hr = t.Hour;
int m = t.Minute;
if (!(hr >= 9 && hr < 10 || (hr == 10 && m == 0))) {
Console.WriteLine("Enter the reason for not coming within the valid time:");
else