What is an Event?
In the first fourteen parts of the C# Object-Oriented Programming tutorial we have described the creation of classes with methods, properties and other structures. Each of these is similar because it allows a direct command to be given to a class or object within the flow of a program. This is similar to the early programming languages, which simply processed a sequence of commands and loops until complete.
The sequential or procedural method of programming is limited to this type of processing. However, C#'s object-oriented approach is also event-driven. This means that as activities occur, a class may raise events to indicate the action that happened and to pass related information to other classes that have subscribed to the event. These may be used for various purposes including indicating the progress of a long-running process.
A key advantage of using events is that a class that publishes an event does not need to know the details of the subscribers at design-time. As events are based upon delegates, the subscribers are only added when the program is running.
Creating an Event
There are three parts to creating an event handler within a class. Firstly a delegate is required. The delegate is used to hold the details of the subscribers to the event. Secondly, a public event is created. This event is visible externally to the class and used for creating the event subscriptions. It is also the member that is visible using Visual Studio's Intellisense feature. Finally, a method is created within the class. The method contains the code that fires the event. Each of these three elements is described in the following sections.
To provide an example of the use of events, we will create a new program containing a class that represents a car. When the car's speed exceeds a safety limit, an event will be fired. To begin, create a new console application named "EventDemo". Add a class file named "Car" to the project and add the following code to the class to create a read-only Speed property and an Accelerate method. The _safetySpeed variable holds the maximum speed permitted and will be used later.
public class Car
private int _speed = 0;
private int _safetySpeed = 70;
public int Speed
public void Accelerate(int mph)
_speed += mph;
Creating the Delegate
The delegate for an event is declared using the standard syntax for any delegate. However, it should be declared with a data type of void as events are multicasting. This means that multiple subscribers can be attached to a single event with each being notified of the event in turn.
The delegate's signature is important as this is the signature that subscribers will see. To comply with the expected standards, the signature should contain two parameters. The first parameter should be an object named 'source'. This will contain a reference to the object that raised an event. The second parameter should be of the type EventArgs and should be named 'e'. EventArgs is a special class that can be derived from to create custom classes for passing information when an event fires. This is described later in this article.
In this example we will add an event to the Car class that is raised when the car exceeds the safety limit speed. To create the delegate for this event, add the following code to the namespace (outside of the class definition).
public delegate void SpeedLimitExceededEventHandler(object source, EventArgs e);
Declaring the Event
The event is the publicly visible element of the class. It can be subscribed to by other classes that wish to react to the event being fired. The event is declared by prefixing its name with the event keyword and the name of the delegate that the event will be based upon. To create the event for the Car class, add the following to the class:
public event SpeedLimitExceededEventHandler SpeedLimitExceeded;
Creating an Event Method
An event method is a single method used to raise an event. Although it is not strictly necessary to create such a method, it is advantageous as it makes maintenance of the code simpler and allows derived classes to override the functionality and alter the manner in which events are fired.
To create the event method for the SpeedLimitExceeded event, add the following code to the Car class.
public virtual void OnSpeedLimitExceeded(EventArgs e)
if (SpeedLimitExceeded != null) SpeedLimitExceeded(this, e);
There are several items to note in this method. Firstly, the method is marked as virtual. This keyword will be described in detail later in the tutorial. It means that the functionality of this method may be overridden and changed by classes that are derived from the Car class.
The method is named using the name of the event and the prefix 'On'. This is a simple convention that developers expect to see. The event method requires only a single parameter containing the event arguments for the raised event. This parameter holds all of the information that is to be passed to the event subscribers.
Within the method's code block, an if statement checks to see if the event is set to null. This conditional statement checks that there is at least one subscriber to the event as if there are no subscribers, firing the event would cause an exception to be thrown. If the test is passed, the event is raised as if it where a method, passing a reference to the current object and the event arguments that were passed in the parameter.
3 February 2008