Delegate: A method can be passed as a parameter to another method through a delegate. If we create a bubble sort method, we cannot change the main code of the bubble sort; instead, we can pass new conditions as parameters to the bubble sort method.

A delegate is a variable that holds a reference to a method. You can also think of it as a pointer to a function. A delegate can refer to more than one method with the same return type and parameters.

When and why to use delegate?

When we need to pass a method as a parameter

delegate int Calculator(int x, int y);
 
class Program
{
    public static int Add(int x, int y)
    {
        return x + y;
    }
 
    public static int Mul(int x, int y)
    {
        return x * y;
    }
 
    public static void Main(string[] args)
    {
        Calculator c1 = Add;
        int result = c1(10, 20); 
        Console.WriteLine(result); // 30
    }
}

·  There are many type of delegate exists. Here is some examples:

Delegate TypeDescriptionExample
ActionMethod with parameters, no return valueAction, Action, Action<T1, …, T16>
FuncMethod with parameters, returns a valueFunc, Func<T, TResult>, Func<T1, …, TResult>
PredicateSpecial case of Func<T, bool> for boolean conditionsPredicate
ComparisonMethod for comparing two objects for orderingComparison
EventHandlerMethod that handles an eventEventHandler, EventHandler
ConverterMethod that converts one type to anotherConverter<TInput, TOutput>
Action<T1, …, T16>Method with up to 16 parameters, no return value-
Func<T1, …, TResult>Method with up to 16 parameters, returns a value-
MulticastDelegateBase class for delegates supporting multicast invocation-

·         Example Func and Action: (We can’t use params keyword in Func and Action)

// Func (A type of delegate)
Func<int, int, int> add = (a, b) => a + b;
int result = add(5, 10); // Result is 15
 
// Action (A type of delegate)
Action<string> printMessage = (message) => Console.WriteLine(message);
printMessage("Hello, World!"); // Outputs: Hello, World!

More Details on Delegates & Events

Why Use Delegates?

Programmers often need to pass a method as a parameter to another method. Delegates are created for this purpose. Delegates were introduced in C# 1.0. In C#, a delegate encapsulates a method signature, and although it can be used in many contexts, it is often fundamental in event-handling models.

What is a Delegate?

In simple terms, a delegate holds references to methods and can invoke them when needed. You can attach multiple methods to a delegate and invoke them collectively.

Benefits of Delegates

  1. Object-Oriented: Delegates are type-safe and secure.
  2. Simplified Event Handling: Makes managing events straightforward.
  3. Parameter Passing: Allows methods to be passed as parameters.
  4. Callback Mechanism: Useful for implementing callback methods.
  5. Encapsulation: Provides a clean way to encapsulate methods.
  6. Event Handling: Primarily used for events and callbacks.
  7. Anonymous Methods: Enables invocation of anonymous methods.

How to Define a Delegate*

  1. Declare a Delegate: Define the delegate type.
  2. Assign a Target Method: Attach methods to the delegate.
  3. Invoke the Delegate: Call the methods through the delegate.

Types of Delegates in

  1. Single Delegate: Points to one method at a time.
  2. Multicast Delegate: Points to multiple methods.
  3. Generic Delegate: Used for generic types and methods.

Understanding Events

In C#, an event allows one object to notify other objects about specific actions or conditions. Events are implemented using delegates to define event handlers.

Example: Delegates and Events in Action

using System;
 
// Define a delegate type
delegate void MyDelegate(string message);
 
class Publisher
{
    // Declare an event based on the delegate
    public event MyDelegate OnPublish;
 
    public void PublishNews(string news)
    {
        Console.WriteLine("Publishing news: " + news);
 
        // Trigger the event if there are subscribers
        OnPublish?.Invoke(news);
    }
}
 
class Subscriber
{
    public void Subscribe(Publisher publisher)
    {
        // Add method to the event delegate
        publisher.OnPublish += DisplayNews;
    }
 
    public void Unsubscribe(Publisher publisher)
    {
        // Remove method from the event delegate
        publisher.OnPublish -= DisplayNews;
    }
 
    // Event handler method
    void DisplayNews(string news)
    {
        Console.WriteLine("Received news: " + news);
    }
}
 
class Program
{
    static void Main()
    {
        Publisher newsPublisher = new Publisher();
        Subscriber subscriber1 = new Subscriber();
        Subscriber subscriber2 = new Subscriber();
 
        // Subscribers subscribe to the event
        subscriber1.Subscribe(newsPublisher);
        subscriber2.Subscribe(newsPublisher);
 
        // Publish news
        newsPublisher.PublishNews("Thanks for subscribing!");
 
        // Unsubscribe one subscriber
        subscriber1.Unsubscribe(newsPublisher);
 
        // Publish more news
        newsPublisher.PublishNews("Stay informed with more updates!");
    }
}

Output

Publishing news: Thanks for subscribing!
Received news: Thanks for subscribing!
Received news: Thanks for subscribing!
Publishing news: Stay informed with more updates!
Received news: Stay informed with more updates!