14 January 2015

events in c# - explained in detail

Events are an important concept in object-oriented programming (OOPS). In this article let's discuss what are events, how to declare events in C#, when to use events, how to subscribe to an event, etc.

What are events

Events are the mechanism to let know something interesting has occurred. The source entity which raises the event is called as an event raiser. And the entities which are interested in the event are known as event subscribers.

How to declare events in C# language

Its always better to start with an example whenever learning a new thing. Let's consider the below event declared in C#.
public event BalanceChangedEventHandler BalanceChanged;
  • Where event is keyword used to declare events in C#.
  • Event declared is a type BalanceChangedEventHandler delegate. A event will be declared for a specific delegate type. So you need to decide on delegate to be used before declaring an event.
  • Next, you need to give a appropriate name to a event. In this case BalanceChanged is the event name.
  • As always you specify the visibility of a class member using access specifiers.

Why and when to use events

Let's consider you have got BankAccount class. Whenever the account's balance changes you need to let know the consumers of account class about the balance change. In such requirements, you can make use of events.

Events uses a delegate to maintain the list of subscribers. Delegates hold the references of the subscribed event handling methods. But doesn't aware of the classes which have defined events handling methods. That means the class which raises the event doesn't have a direct coupling with the class which has subscribed to the event. So using events makes the classes in the application loosely coupled with each other. This is advantage of using the events and delegates in the application design.

public class BankAccount
{

// Declare delegate
public delegate void BalanceChangedEventHandler
 (object sender, BalanceChangedEventArgs args);

 // Declare event 
 public event BalanceChangedEventHandler BalanceChanged;

 public double _balance;
 public double Balance
  {
    get
    {
      return _balance;
    }
    set
    {
      if (_balance == value)
          return;

      double previousBalance = _balance;
      _balance = value;

       // Raise the event on balance changed
       OnBalanceChanged(previousBalance);
     }
    }
 protected void OnBalanceChanged(double previousBalance)
  {
   // Check if anyone has been subscribed to event
   // If no one has subscribed BalanceChanged will be null
   if (this.BalanceChanged != null)
    {
    BalanceChanged(this
     new BalanceChangedEventArgs(previousBalance, _balance));
    }
  }
}

Let’s dissect above BankAccount class.

  • Declaring a delegate

    public delegate void BalanceChangedEventHandler
    (object sender, BalanceChangedEventArgs args);

    BalanceChangedEventHandler is a delegate matching a method which accepts sender of type object and another argument of type BalanceChangedEventArgs. BalanceChangedEventArgs is a class deriving from EventArgs. EventsArgs will be declared something like below.

    public class BalanceChangedEventArgs:EventArgs
    {
       public decimal PreviousBalance { get; private set; }
       public decimal NewBalance { get; private set; }

       public BalanceChangedEventArgs(decimal previousBalance, 
            decimal newBalance)
       {
          PreviousBalance = previousBalance;
          NewBalance = newBalance;
       }
    }
  • Declaring an event

    BalanceChanged is a event of type BalanceChangedEventHandler delegate. The event will pass the information to subscribers using BalanceChangedEventArgs object.

  • Raising an event

    OnBalanceChanged() method is used to raise an event. Whenever there is a change in the Balance value, the BankAccount class is raising the event. In the event raising method you will check whether anyone has subscribed to a event, if yes then event will be raised by passing in the sender and the event arguments.

    protected void OnBalanceChanged(double previousBalance)
     {
       // Check if anyone has been subscribed to event
       // If no one has subscibed BalanceChanged will be null
       if (this.BalanceChanged != null)
          {
           BalanceChanged(this
               new BalanceChangedEventArgs(previousBalance, _balance));
          }
     }

    Sender is the object raising the event. In this case it is BackAccount object.

    Event argument BalanceChangedEventArgs is used to send new balance and previous balance amount. i.e. Event argument is used to pass event details.

Subscribing to event in C#

We learned about how to declare events and raise events. The whole purpose of the event is to let know some object state has been changed to its subscribers. Now let's see how can we subscribe to events.

In C# language we will subscribe to the event by using overloaded '+' operator. Let's go through an example.

class Program
{
  static void Main(string[] args)
    {
      BankAccount bankAccount = new BankAccount();

       // Subscribe to an event
       bankAccount.BalanceChanged += BankAccount_BalanceChanged;
       bankAccount.Balance = 10;

       // do some other process
       // Before the subscriber object being destroyed 
       // unsubscribe to an event
       bankAccount.BalanceChanged -= 
            BankAccount_BalanceChanged;
        Console.ReadLine();
     }
   static void BankAccount_BalanceChanged(object sender,
              BalanceChangedEventArgs args)
     {
       Console.WriteLine("Balance= {0}", args.NewBalance);
     }
}
  • In the above console application example has subscribed to BankAccount object BalanceChanged event using overloaded '+' operator. While subscribing to the event, you need to mention what the event handler method.Here the Console application is called the subscriber for the event.

    In Visual Studio "thunder icon" is used to represent the event as shown in the above event subscription screenshot.

  • After the event subscription, the subscribers will be notified whenever an event occurs. In our current C# example, we are assigning a new value to Balance property on the BankAccount object, which results in an event being raised. Hence the subscribed event handler "BankAccount_BalanceChanged" method will be invoked.
  • Interesting thing is event arguments. In our example the event argument passed is BalanceChangedEventArgs. It will indicate two things, new balance amount (new state) and previous balance (old state). The BankAccount_BalanceChanged event handling method is making use of the event argument to print the new balance.

Unsubscribing to events in C#

Once you subscribed to an event, you should always unsubscribe to the event. Event unsubscribing is like telling the event raiser that you are no longer interested in the event. During event un-subscription, your event handling method will be removed from the notification list what your event raiser maintains. Make it a practice to always unsubscribing to an event otherwise it may lead to memory leaks in your application.

Event subscription will be done using overloaded '-' minus operator like below:

// Event will be unsubscribed using overloaded
// minus (-) operator.
bankAccount.BalanceChanged -= BankAccount_BalanceChanged;

Download sample tutorial project

You can download the C# events tutorial project from the google drive share.

No comments:

Post a Comment