Tải bản đầy đủ (.pdf) (22 trang)

Delegates and Events pot

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (640.85 KB, 22 trang )

Delegates and
Events
Chapter 12
Classes 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

¤NIIT Delegates and Events 12.3
Delegates 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
12.4 Delegates and Events ¤NIIT
Create 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()
{
//Delegate Instantiation
MyDelegate DelegateObject = new MyDelegate(DelegateFunction);
}
In the preceding example, the signature and return type of DelegateFunction matches
with the delegate declaration of the
MyDelegate delegate. the MyDelegate delegate can
hold the address of
DelegateFunction. DelegateObject is a delegate object of the type,
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
using System;
using System.IO;
// Program to write the data to the console and file
namespace Chapter12_Ex1

{
public class PrintToDevice
{
Instantiating Delegates
Using Delegate
¤NIIT Delegates and Events 12.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)
{
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);
s= s + " File";
//Writing a string to the file
SWriter.WriteLine(s);
//removing the content from the buffer
SWriter.Flush();
SWriter.Close();
FStream.Close();

}
//Method to send the string data to respective methods
public static void DisplayData(PrintData PMethod)
{
PMethod("This should go to the");
}
public static void Main()
{
//Initializing the Delegate object

PrintData Cn = new PrintData (WriteConsole);
PrintData Fl = new PrintData (WriteFile);
//Invoking the DisplayData method with the Delegate
object as the argument
//Using Delegate
DisplayData (Cn);
DisplayData (Fl);
Console.ReadLine();
}
}
}
In the preceding example, the WriteConsole() and WriteFile() methods are used to
write the information to the screen and to the file. The delegate variable
PrintData is
used to refer to the
WriteConsole() and WriteFile() methods.
Delegates are of two types and depending upon the requirement of the application the
suitable type of delegate is selected.
12.6 Delegates and Events ¤NIIT
There 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
of a multicast delegate.
Multicast delegates hold the reference of more than one method therefore, if you call a
multicast delegate it will execute all the methods it wraps in the calling order. The
multiple methods called by the delegate in this case should not return any value because
several multicast delegates are called consecutively and you cannot wait to get the return
value from each of these methods.
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
¤NIIT Delegates and Events 12.7
using System;
using System.IO;
// Program to write the data to the console and file
namespace Chapter12_Ex2
{
public class PrintToDevice
{
//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)
{
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);
s= s + " File";
//Writing a string to the file
SWriter.WriteLine(s);
//removing the content from the buffer
SWriter.Flush();
SWriter.Close();
FStream.Close();
}
//Method to send the string data to respective methods
public static void DisplayData(PrintData PMethod)
{
PMethod("This should go to the");
}
public static void Main()
{
//Initializing the Delegate object
PrintData MlDelegate = new PrintData(WriteConsole);
MlDelegate += new PrintData(WriteFile);
DisplayData(MlDelegate);
MlDelegate -= new PrintData(WriteFile);
DisplayData(MlDelegate);
}
}
}
12.8 Delegates and Events ¤NIIT
Just 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
¤NIIT Delegates and Events 12.9
<
An 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
12.10 Delegates and Events ¤NIIT
The 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
¤NIIT Delegates and Events 12.11
A 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;
12.12 Delegates and Events ¤NIIT
N
ote
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.
¤NIIT Delegates and Events 12.13
The 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)
{
this.Hour=Hour;
this.Minute=Minute;
this.Second=Second;
}
public int GetHour
{
return Hour;
}
public int GetMinute
{
return Minute;
}
public int GetSecond
{

return Second;
}
}
The TimeInfoEventArgs class is the event class that will pass the value of hour, minute
and second. The class declares three accessor methods:
GetHour, GetMinute, and
GetSecond.
Passing Event Parameters
12.14 Delegates and Events ¤NIIT
,
Problem Statement
In an air-conditioner manufacturing company, the working time is from 9 AM to 6 PM.
The management of the company is flexible and it allows workers to arrive to work late
by 1 hour. The entry time of workers is recorded electronically in a log file when they
enter the premises of the company. The application used for recording the attendance of
each worker needs to log the appropriate information.
Help 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
¤NIIT Delegates and Events 12.15
5. 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:
using System;
using System.IO;
namespace AttendanceApp
{
// Event Publisher
public class DelegateEvent
{
// Define a delegate named AttendanceLogHandler, which will
encapsulate
// any method that takes a string as the parameter and

returns no value
public delegate void AttendanceLogHandler(string Message);
// Define an Event based on the above Delegate
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:");
Reason = Console.ReadLine();
}
OnEventLog("Logging the info :" + UserName);
if (hr >= 9 && hr < 10 || (hr == 10 && m == 0))
if (m<10)
OnEventLog(" Logged in at " +
hr.ToString()+":0"+m.ToString() + " Within
Time");
else
12.16 Delegates and Events ¤NIIT
OnEventLog(" Logged in at " + hr.ToString() +

":"+m.ToString() + " Within Time");
else
if (m<10)
OnEventLog(" Logged in at " + hr.ToString()+ ":0"+
m.ToString() + " not Within Time because " +
Reason);
else
OnEventLog(" Logged in at " + hr.ToString() +":"+
m.ToString() + " not Within Time because " +
Reason);
OnEventLog(" ");
}
// By Default, create an OnZZZZ Method, to call the Event
protected void OnEventLog(string Message)
{
if (EventLog != null)
{
EventLog(Message);
}
}
}
// The AttendanceLogger class merely encapsulates the file
I/O
public class AttendanceLogger
{
FileStream FileStr;
StreamWriter StreamWrtr;
// Constructor
public AttendanceLogger(string FileName)
{

FileStr = new FileStream(FileName, FileMode.Append,
FileAccess.Write);
StreamWrtr = new StreamWriter(FileStr);
}
// Member Function which is used in the Delegate
public void Logger(string LogInfo)
{
StreamWrtr.WriteLine(LogInfo);
}
public void Close()
{
StreamWrtr.Close();
FileStr.Close();
}
}
//Subscriber of the Event
public class RecordAttendance
{
¤NIIT Delegates and Events 12.17
static void Logger(string LogInfo)
{
Console.WriteLine(LogInfo);
}
static void Main(string[] args)
{
AttendanceLogger FileLog = new
AttendanceLogger("c:\\process.log");
DelegateEvent DEvent = new DelegateEvent();
// Subscribe the Functions Logger and FileLog.Logger
DEvent.EventLog += new

DelegateEvent.AttendanceLogHandler(Logger);
DEvent.EventLog += new
DelegateEvent.AttendanceLogHandler(FileLog.Logger);
// The Event will now be triggered in the LogProcess()
Method
DEvent.LogProcess();
Console.ReadLine();
FileLog.Close();
}
}
}
Task 3: Building and Executing an Application
To build and execute the application, you need to perform the following steps:
1. Select Ctrl+Shift+b or press F6 to build the solution.
2. Select DebugÆStart Debugging or press F5 to execute the application.
3. Verify the output of the application.
12.18 Delegates and Events ¤NIIT
The following window verifies the output of the executed program.
Output of the Attendance Log Application
¤NIIT Delegates and Events 12.19
,
1. Identify the correct statement about delegates.
a. Before you declare an event inside a class, you can optionally declare a delegate
by using the delegate keyword.
b. The delegate type consists of the set of arguments that it receives from the
method that handles the event.
c. Multiple events cannot share the same delegate.
d. By using a single-cast delegate, you can invoke only one method corresponding
to different events.
2. Which of the following code is correct to assign more than one method address to a

delegate?
a.
Delegatevariable = new MyDelegate(Function1)
Delegatevariable += new MyDelegate(Function2)
b. Delegatevariable = MyDelegate(Function1);
Delegatevariable += MyDelegate(Function2);
c. Delegatevariable = new MyDelegate(Function1);
Delegatevariable += new MyDelegate(Function1+Function2);
d. Delegatevariable = new MyDelegate(Function1);
Delegatevariable += new MyDelegate(Function2);
3. State whether the given statement is true or false.
A publisher is an object that contains the definition of the event and the delegate.
4. Match the following delegate concepts with there implementation.
Delegate Implementation Syntax
Declaring Delegates TestDelegate Var=new TestDelegate(Func);
Instantiating Delegates public delegate void TestDelegate(string arg);
Using Delegates TestDelegate( “Test”);
5. State whether the given statement is true or false.
Delegates used with the events should be declared void.
Practice Questions
12.20 Delegates and Events ¤NIIT
In this chapter, you learned that:
 Delegates allow you to write code that can dynamically change the methods that it
calls.
 There are two types of delegates, Single-cast delegate and Multicast delegate.
 A single-cast cast delegate can call only one function.
 Multicast delegate holds the reference of more than one method.
 Single-cast delegate derives from the System.Delegate class and Multicast delegate
derives from the
System.MulticastDelegate.

 Events are the messages sent by an object to indicate the occurrence of an event.
 Events use the publisher and subscriber model.
 A publisher is an object that maintains its internal state.
 A subscriber is an object that registers an interest in an event.
Summary
¤NIIT Delegates and Events 12.21
,,,
Exercise 1
Write an application that creates a class named Registration. The application would be
used by the counselors of an IT education center, while registering students. The
registration data entry is done differently for Career registration and for Modular
registration. Your application should have separate class for the two categories of
students. You need to record the student’s score of the aptitude test for Career
registration. You need to record the student’s prior experience or knowledge for Modular
registration.
Hint: Use delegate in the registration class while registering a student to call the
appropriate methods.
Exercises
12.22 Delegates and Events ¤NIIT

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×