Nutshell Series

C# Delegates and Events – Explained

Delegates and events in C# are foundational concepts that enable flexible, type-safe method references and event-driven programming. Many developers find them confusing at first, but this guide explains them in a simple, easy-to-understand way.


What is a Delegate?

A delegate is a type-safe object that holds a reference to a method with a specific signature. Delegates are similar to function pointers in C or C++, but they are object-oriented, type-safe, and secure.

Delegates allow you to pass methods as parameters to other methods or assign methods at runtime.

// Define a delegate
public delegate int MathOperation(int x, int y);

// Method matching the delegate signature
public class Calculator
{
    public int Add(int a, int b) => a + b;
    public int Multiply(int a, int b) => a * b;
}

// Using the delegate
MathOperation operation = new Calculator().Add;
int result = operation(5, 3); // Output: 8

The delegate’s signature (return type + parameters) must match the method it references. This allows delegates to be used as **callbacks** or **pluggable methods** in your code.


Delegate Magic

Delegates are special objects. Unlike normal objects that contain data, a delegate only contains information about a method.
Delegates do not depend on the class of the object they reference; only the method signature matters.
This allows anonymous method invocation and runtime flexibility.


Benefits of Delegates

  • Type-safe: Ensures the method signature matches.
  • Object-oriented: Fully compatible with OOP principles.
  • Secure: No unsafe pointers.
  • Flexible: Can be used to pass methods around, define callbacks, and plug in new behavior dynamically.

Types of Delegates

C# delegates come in two main types:

1. Singlecast Delegate

A singlecast delegate points to a single method at a time.

public delegate void Notify(string message);

public class Messenger
{
    public void ShowMessage(string msg)
    {
        Console.WriteLine(msg);
    }
}

// Using singlecast delegate
Notify notify = new Messenger().ShowMessage;
notify("Hello World!"); // Only calls ShowMessage

2. Multicast Delegate

A multicast delegate can reference multiple methods. Delegates in C# are multicast by default and derived from System.MulticastDelegate.

public delegate void Notify(string message);

public class Messenger
{
    public void ShowMessage(string msg)
    {
        Console.WriteLine(msg);
    }

    public void LogMessage(string msg)
    {
        Console.WriteLine("Log: " + msg);
    }
}

Messenger m = new Messenger();
Notify notify = m.ShowMessage;
notify += m.LogMessage; // Add second method

notify("Hello World!");
// Output:
// Hello World!
// Log: Hello World!

Events in C#

An event is a mechanism that allows a class to notify other classes or objects when something happens.
Events are based on delegates and are widely used in GUI programming, data binding, and event-driven applications.

// Declare a delegate for the event
public delegate void ThresholdReachedEventHandler(int threshold);

// Class that publishes the event
public class Counter
{
    public event ThresholdReachedEventHandler ThresholdReached;
    private int total;

    public void Add(int x)
    {
        total += x;
        if (total >= 10)
        {
            ThresholdReached?.Invoke(total); // Trigger event
        }
    }
}

// Class that subscribes to the event
public class Listener
{
    public void OnThresholdReached(int value)
    {
        Console.WriteLine($"Threshold reached: {value}");
    }
}

// Usage
Counter counter = new Counter();
Listener listener = new Listener();

counter.ThresholdReached += listener.OnThresholdReached;
counter.Add(5);
counter.Add(6); // Triggers event

In this example, the Counter class fires the ThresholdReached event when a certain total is reached,
and the Listener responds to it.


Steps to Define and Use Delegates

  1. Declare a delegate with a method signature.
  2. Create methods matching the delegate signature.
  3. Create a delegate instance and assign methods.
  4. Invoke the delegate.
  5. (Optional) Use multicast delegates or events.

Summary Table

Concept Definition Example
Delegate Type-safe reference to a method MathOperation delegate
Singlecast Delegate Points to a single method Notify notify = messenger.ShowMessage;
Multicast Delegate Points to multiple methods notify += messenger.LogMessage;
Event Notifies other classes when something happens, based on delegates ThresholdReached event
Anonymous Delegate Delegate without a named method notify = delegate(string msg) { Console.WriteLine(msg); };
Callback Method passed via delegate to be called later MathOperation used as parameter

Leave a comment