Creating and Using Events

Tutorial 2 of 5

Introduction

In this tutorial, we are going to understand how to create and use events in C#. Events are a very fundamental concept in programming that allow us to handle certain actions that occur during the runtime of our programs, such as button clicks or key presses.

By the end of this tutorial, you will be able to:

  • Understand what events are in C#
  • Create your own events
  • Use events in your programs

Prerequisites:

  • Basic knowledge of C# programming
  • Understanding of classes and objects in C#

Step-by-Step Guide

Events in C# are a way for a class to provide notifications to clients of that class when some interesting thing happens to an object. The most familiar use for events is in graphical user interfaces; typically, the classes that describe controls in the interface have events that are notified when the user does something to the control (for example, click a button).

Let's start by creating an event and then using that event in our program.

Creating an Event

Creating an event requires a delegate. The delegate defines the signature for the event handler method of the subscriber class. For example:

public delegate void MyEventHandler(string foo);

Then we use this delegate to declare an event inside our class:

public event MyEventHandler MyEvent;

Using an Event

To use an event, we need to subscribe to it. This is usually done from another class:

publisher.MyEvent += new Publisher.MyEventHandler(HandleEvent);

The HandleEvent is a method that will be called whenever the MyEvent is triggered:

void HandleEvent(string foo)
{
    Console.WriteLine(foo);
}

Code Examples

Example 1: Basic Event

Here we have a basic example of creating and using an event.

public class Publisher
{
    public delegate void MyEventHandler(string foo);
    public event MyEventHandler MyEvent;

    public void RaiseEvent()
    {
        MyEvent?.Invoke("Hello, World!");
    }
}

public class Subscriber
{
    public void Subscribe(Publisher pub)
    {
        pub.MyEvent += HandleEvent;
    }

    void HandleEvent(string foo)
    {
        Console.WriteLine(foo);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Publisher pub = new Publisher();
        Subscriber sub = new Subscriber();

        sub.Subscribe(pub);
        pub.RaiseEvent(); // Output: "Hello, World!"
    }
}

Summary

In this tutorial, we have covered:

  • What events are in C#
  • How to create an event using delegates
  • How to subscribe to an event and handle it

Next steps for you would be to explore more about delegates, events, and how they can be used in real-world applications.

Practice Exercises

  1. Create a class 'Alarm' that triggers an event 'AlarmRang' every time its method 'Ring' is called. Subscribe to this event and print a message to the console each time the event is triggered.

  2. Create a class 'BankAccount' with a 'BalanceChanged' event that gets triggered every time the balance changes. Subscribe to this event and print the new balance to the console each time it changes.

Solutions

// Exercise 1
public class Alarm
{
    public delegate void AlarmHandler();
    public event AlarmHandler AlarmRang;

    public void Ring()
    {
        AlarmRang?.Invoke();
    }
}

public class AlarmListener
{
    public void WakeUp()
    {
        Console.WriteLine("Alarm rang. Time to wake up!");
    }

    public void SubscribeToAlarm(Alarm alarm)
    {
        alarm.AlarmRang += WakeUp;
    }
}

// Usage
var alarm = new Alarm();
var listener = new AlarmListener();
listener.SubscribeToAlarm(alarm);
alarm.Ring(); // Outputs: "Alarm rang. Time to wake up!"


// Exercise 2
public class BankAccount
{
    private decimal balance;
    public delegate void BalanceChangedHandler(decimal newBalance);
    public event BalanceChangedHandler BalanceChanged;

    public void Deposit(decimal amount)
    {
        balance += amount;
        BalanceChanged?.Invoke(balance);
    }

    public void Withdraw(decimal amount)
    {
        balance -= amount;
        BalanceChanged?.Invoke(balance);
    }
}

public class BankAccountUser
{
    public void PrintBalance(decimal balance)
    {
        Console.WriteLine($"The new balance is: {balance}");
    }

    public void SubscribeToBankAccount(BankAccount account)
    {
        account.BalanceChanged += PrintBalance;
    }
}

// Usage
var account = new BankAccount();
var user = new BankAccountUser();
user.SubscribeToBankAccount(account);
account.Deposit(100); // Outputs: "The new balance is: 100"
account.Withdraw(30); // Outputs: "The new balance is: 70"