0% found this document useful (0 votes)
22 views9 pages

Lect05 - Events

This document discusses delegates and events in C#. It explains that delegates allow methods to be indirectly invoked by holding references to them. Events use delegates to allow classes to notify other classes of events, like a button click. The standard event handler in C# is EventHandler, which takes an object source and EventArgs as parameters to pass event information. An example demonstrates creating a Car class with Exploded and AboutToExplode events that are handled using delegates and the standard EventHandler.

Uploaded by

2151150038
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
22 views9 pages

Lect05 - Events

This document discusses delegates and events in C#. It explains that delegates allow methods to be indirectly invoked by holding references to them. Events use delegates to allow classes to notify other classes of events, like a button click. The standard event handler in C# is EventHandler, which takes an object source and EventArgs as parameters to pass event information. An example demonstrates creating a Car class with Exploded and AboutToExplode events that are handled using delegates and the standard EventHandler.

Uploaded by

2151150038
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 9

Lecture 05: Delegates And Events

Objectives:
 Learn about delegates, how to create them and how to use them.
 Learn about special types of delegates called events.
 Learn how to use the standard event handler.

1. Delegates

A Delegate is a class whose declaration syntax is different from that of a


normal class.

It is used to hold references to methods, so that when it is invoked, it


automatically invokes all methods associated with it.

Thus, a delegate gives an indirect access to a method or methods, hence


the name delegate.

To see how delegates are declared and used, consider the following
example.

Example 1:
using System;

public class DelegateExample {


public delegate void PrintingDelegate(String s);

public static void Writer1(String s) {


Console.WriteLine("From Writer1: "+s);
}

public static void Writer2(String s) {


Console.WriteLine("From Writer2: "+s);
}

public static void Main() {


PrintingDelegate d = new PrintingDelegate(Writer1);
d("Hello There");

//can point to more than one method


d += new PrintingDelegate(Writer2);
Console.WriteLine();
d("Hello There");

//can also point to instance method


Console.WriteLine();
MessageWriter mw = new MessageWriter();
d+= new PrintingDelegate(mw.WriteMessage);
d("Hello There");

//You can also remove a method


Console.WriteLine();
d-= new PrintingDelegate(Writer1);
d("Hello There");
}
}

public class MessageWriter {


public void WriteMessage(String s) {
Console.WriteLine("From MessageWriter: "+s);
}
}
Delegate declaration
Notice that although delegate is a class, its declaration syntax is very
similar to that of a method.

It is designed this way because a delegate can only hold references to


specific types of methods – those methods whose signature matched that
of the delegate.

Thus, in our example, the PrintingDelegate can only hold references to


methods of the form:
[static] void MethodName(String s)

As the above example shows, such methods can be static or instance.

The above example declares the delegate as a nested class. This is


usually how it is done, but in fact, a delegate can be declared on its own,
like any other class.

Instantiating a Delegate
Before you create an instance of a delegate, you must have a method
that you wish to associate that instance with. As we can see from the
example, the syntax is:
DelegateType delegateVar = new DelegateType(methodName);

Notice that the method name must NOT be followed with parameters.
Actually a method name without parameter means a reference to the
method. So the above statement assigns the method reference to the
delegateVar delegate instance.

Multicast Delegates
Internally, a delegate uses a linked list to hold references to the methods
associated with it. Thus, a delegate instance can hold references to more
than one method.

In fact internally, a delegate is declared as a subclass of the


System.MulticastDelegate class, which in turn derives from the
System.Delegate class. Thus, a delegate automatically inherits the
methods of these classes. Check the methods inherited from these
classes in the documentation.
Once a delegate instance has been created, we can assign more method
references to it using the overloaded, += operator, or using the static
Combine method of the Delegate class.

Similarly, a method reference can be removed from a delegate instance


using the overloaded, -= operator or using the static Remove method of
the Delegate class.

Invoking a Delegate
As we saw in the example, a delegate instance is invoked based on its
method-like signature. In our example, since the associated methods
are void, we simply call it as:
d(string)

This will automatically call methods associated with the delegate.

2. Events

A common application of delegates is in GUI programming where they


are used as call-back methods.

That is, a class representing a GUI control such as the Button class will
declare a public field for a delegate which it will invoke when the button
is clicked.

An application that wishes to be notified when the button is clicked will


write a method that should be executed when the button is clicked, and
use the method to register with the delegate field.

When the user clicks the button, the method is automatically executed.

This procedure will work fine except for one problem – the delegate field
is public.

This means other classes (other than the Button class) can invoke the
delegate - thus raising a false alarm. In fact, the field can be assigned a
new instance by another class – thus canceling any registration to the
delegate made by other classes.

To solve this problem, C# introduced the event modifier.


If a delegate field is declared with the event modifier, then only the class
in which it is declared can invoke it.

Also, the only operators allowed on event delegates (simply called


events) outside their class of declaration are: += and -=. Thus, other
classes can only register themselves with the events on cancel their
earlier registration.

Example 2: The following shows an example of using event-qualified delegates.


using System;

public delegate void EngineMonitor(String s);

public class Car {


private int currentSpeed = 0;
private bool isDead = false;
private int maxSpeed;
private String name;

public event EngineMonitor Exploded = null;


public event EngineMonitor AboutToExplod = null;

public Car(String name, int maxSpeed){


this.name = name;
this.maxSpeed = maxSpeed;
}

public void Accelerate(int increment) {


if (isDead) {
if (Exploded != null)
Exploded("The car has exploded");
}
else {
currentSpeed += increment;
if (currentSpeed >= maxSpeed) {
isDead = true;
if (Exploded != null)
Exploded("The car has exploded");
}
else if (currentSpeed + 20 >= maxSpeed &&
AboutToExplod != null)
AboutToExplod("Dangerous Speed:"+currentSpeed+", Car
about to explod");
else
Console.WriteLine("Current Speed = "+currentSpeed);

}
}
}

public class EventExample {


public static void Main() {
Car myCar = new Car("Corola", 200);

//register with event source


myCar.Exploded += new EngineMonitor(OnExplod);
myCar.AboutToExplod += new
EngineMonitor(OnAboutToExplod);

//speed up
for (int i=0; i<10; i++)
myCar.Accelerate(20);

//cancel registration to events


myCar.Exploded -= new EngineMonitor(OnExplod);
myCar.AboutToExplod -= new
EngineMonitor(OnAboutToExplod);

//no response
for (int i=0; i<10; i++)
myCar.Accelerate(20);
}

public static void OnExplod(String s) {


Console.WriteLine("Message from car: "+s);
}

public static void OnAboutToExplod(String s) {


Console.WriteLine("Message from car: "+s);
}
}
3. The Standard Event Handler

Because the use of delegates to handle events is very common in GUI


programming, C# has defined a special delegate named, EventHandler,
which is used by most control classes to handle events.

The signature for such delegate is :

void (object source, EventArgs e)

where source is the object that fired the event and e contains any
additional information about the event.

However, the EventArgs class is a class that does not have any fields that
can be used to pass the event information to the client.

If there is a need to send event information, the programmer is expected


to create a sub class from EventArgs, in which the desired fields and
methods can be defined.

Example 3: The following example modifies the Car example to use the standard Event Handler
class.

using System;

public class EventMessage : EventArgs {


private string message;
public EventMessage(string msg) {
message = msg;
}

public string Message {


get {return message;}
}
}

public class Car {


private int currentSpeed = 0;
private bool isDead = false;
private int maxSpeed;
private String name;

public event EventHandler Exploded = null;


public event EventHandler AboutToExplod = null;

public Car(String name, int maxSpeed){


this.name = name;
this.maxSpeed = maxSpeed;
}

public void Accelerate(int increment) {


if (isDead) {
if (Exploded != null)
Exploded(this, new EventMessage("The car has
exploded"));
}
else {
currentSpeed += increment;
if (currentSpeed >= maxSpeed) {
isDead = true;
if (Exploded != null)
Exploded(this, new EventMessage("The car has
exploded"));
}
else if (currentSpeed + 20 >= maxSpeed && AboutToExplod
!= null)
AboutToExplod(this, new EventMessage("Dangerous
Speed:"+
currentSpeed+", Car about to explod"));
else
Console.WriteLine("Current Speed = "+currentSpeed);

}
}
}

public class EventExample {


public static void Main() {
Car myCar = new Car("Corola", 200);

//register with event source


myCar.Exploded += new EventHandler(OnExplod);
myCar.AboutToExplod += new EventHandler(OnAboutToExplod);

//speed up
for (int i=0; i<10; i++)
myCar.Accelerate(20);
//cancel registration to events
myCar.Exploded -= new EventHandler(OnExplod);
myCar.AboutToExplod -= new EventHandler(OnAboutToExplod);

//no response
for (int i=0; i<10; i++)
myCar.Accelerate(20);
}

public static void OnExplod(Object source, EventArgs e) {


Console.WriteLine("Message from car: "+
((EventMessage)e).Message);
}

public static void OnAboutToExplod(Object source, EventArgs


e) {
Console.WriteLine("Message from car: "+
((EventMessage)e).Message);
}
}

You might also like