Events enable an object to notify other objects when something of interest occurs. The object
that raises the event is called the publisher and the objects that handle the event are
called subscribers.
To demonstrate the use of events let’s first create the publisher. This will be a class
that inherits from ArrayList, but this version will raise an event whenever an item is added
to the list. Before we can create the event we first need a delegate that will hold the
subscribers. This could be any kind of delegate, but the standard design pattern is to use
a void delegate that accepts two parameters. The first parameter specifies the source object
of the event and the second parameter is a type that either is or inherits from the System.EventArgs
class. This parameter usually contains the details of the event, but in this case we
don’t need to pass any event data and so we just use the base EventArgs class itself
as the parameter’s type.
With the delegate defined we can create the event using the event keyword followed by
our delegate and the name of the event. The event keyword is used to create a special
kind of delegate that can only be invoked from within the class where it is declared.
Its access level is public so that other classes are allowed to subscribe to this event. The
delegate that follows the event keyword is called an event delegate. In its place we
could alternatively have used the predefined System.EventHandler delegate which is identical
to the one we have just defined. This predefined delegate is used in the .NET class libraries
for creating events that have no event data. The name of the event is commonly a verb.
In this case the event will be raised after the item has been added so we use the past-tense
of the verb "Add". If we created a pre-event instead, which is raised before the actual
event, we would then use the –ing form of the verb, in this case "Adding".
Next, to invoke the event we create an event caller. The naming convention for this method
is to precede the event’s name with the word "On", which in this case becomes OnAdded.
The method has the protected access level to prevent it from being called from an unrelated
class and it is marked as virtual to allow deriving classes to override it. It takes
the event arguments as its one parameter, which in this case is of the EventArgs type.
The method will raise the event only if it is not null. That is, only if the event has
any registered subscribers. To raise it we pass the "this" instance reference as the
sender and the EventArgs object that was passed to the method.
Now that we have an event and a method for calling it we just need to override the ArrayList’s
Add method to make it raise our event. In this overridden version of the method we first
call the base class’s Add method and store its result. We then raise the event with the
OnAdded method by passing it the Empty field in the EventArgs class, which represents an
event with no data. And finally, we return the result to the caller.
To test this publisher class we’ll create a new class that will subscribe to the event.
This class contains an event handler, which is a method that has the same signature as
the event delegate. The name of the handler is commonly the name of the event followed
by the EventHandler suffix. Next, we’ll add a Main method where we create objects
of the Publisher and Subscriber classes. To register the handler in the Subscriber object
to the event in the Publisher object we just need to add the event handler as if the event
was a delegate. Unlike a delegate however, we may not call the event directly from outside
of its containing class. Instead, the event can only be raised by the Publisher, which
in this case occurs when an item is added to that object.