Published on

Delegates

Authors
  • avatar
    Name
    Cristian Pique
    LinkedIn

Introduction

Delegates in C# are a type of object that refers to a method. While they are similar to function pointers in C++, they are type-safe and more secure. They are used to create callback methods and events in C#, allowing for a more flexible and modular code structure.

A delegate is declared using the delegate keyword, followed by the return type and parameter list of the methods that it can refer to. For example, the following code declares a delegate that can refer to any method that takes in two integers and returns an integer:

delegate int MyDelegate(int a, int b);

Once a delegate is declared, it can be instantiated and assigned a method to refer to. This is done using the following syntax:

MyDelegate d = new MyDelegate(MethodName);

where MethodName is the name of the method that the delegate should refer to.

Once a delegate is assigned a method, it can be invoked just like a regular method, using the () operator. For example:

int result = d(5, 10);

This is equivalent to calling MethodName(5, 10) directly.

Delegates can also be used to create callback methods. A callback method is a method that is passed as an argument to another method, and is called by that method at a later time. For example, the following code demonstrates a simple example of using a delegate as a callback method:

using System;

delegate void MyDelegate();

class Program
{
    static void Main()
    {
        MyDelegate d = new MyDelegate(Method1);
        PerformAction(d);
    }

    static void Method1()
    {
        Console.WriteLine("Method1 is called.");
    }

    static void PerformAction(MyDelegate callback)
    {
        callback();
    }
}

In this example, the PerformAction method takes a MyDelegate as a parameter and calls the callback method passed to it. The Main method creates an instance of the delegate and assigns Method1 to it, and then passes it as a parameter to PerformAction, which then calls Method1.

Another important use case for delegates is event handling, which is used to handle user interaction events such as button clicks, mouse movements, etc. For example, the following code demonstrates a simple example of how to use delegates to handle button click events:

class MyButton
{
    public delegate void ClickHandler();
    public event ClickHandler OnClick;

    public void Click()
    {
        if (OnClick != null)
        {
            OnClick();
        }
    }
}

class Program
{
    static void Main()
    {
        MyButton button = new MyButton();
        button.OnClick += new MyButton.ClickHandler(ButtonClicked);
        button.Click();
    }

    static void ButtonClicked()
    {
        Console.WriteLine("Button clicked.");
    }
}

In this example, the MyButton class defines an event called OnClick that is of the delegate type ClickHandler. The Click method of the MyButton class raises the OnClick event. The Main method creates an instance of the MyButton class, and assigns the `ButtonClick

Func, Action, Predicate

In addition to the traditional delegate keyword, C# also provides a set of built-in generic delegate types known as Action, Func, and Predicate. These types are defined in the System namespace and provide a more convenient way to declare and use delegates in certain situations.

Action delegates are used to represent methods that do not return a value. They are defined with a set of generic type parameters, where the last parameter represents the return type, which is always void. For example:

Action<int, string> myAction = (x, y) => Console.WriteLine(x + " " + y);

Func delegates are used to represent methods that return a value. They are defined with a set of generic type parameters, where the last parameter represents the return type. For example:

Func<int, int, int> myFunc = (x, y) => x + y;
int result = myFunc(5, 10);

Predicate delegates are used to represent methods that return a Boolean value. They are defined with a single generic type parameter that represents the input type. For example:

Predicate<string> myPredicate = x => x.StartsWith("A");
bool result = myPredicate("Apple");

These built-in generic delegate types are often used when working with collections in C#, such as the List<T> and Dictionary<TKey, TValue> classes, which provide methods such as Find, FindAll, and RemoveAll that take a delegate as a parameter.

These delegate types provide a more convenient way to declare and use delegates in C#, and are particularly useful when working with collections and other types that make use of delegates as parameters. They are a shorthand of declaring a delegate type, and they also provide a way of indicating the return type and parameters of a delegate.

TL;DR

In conclusion, delegates in C# provide a powerful and flexible mechanism for creating callback methods and handling events. They allow for a more modular and maintainable code structure by separating the implementation of a method from the invocation of that method. Delegates are a key component of the C# language and are widely used in various areas of software development, from event handling to asynchronous programming. Understanding how to use and create delegates is an important aspect of becoming a proficient C# developer. With their strong type-safety and secure nature, delegates offer a powerful tool for creating robust and high-performing applications. They are widely used in various areas of software development and understanding their use cases is important for becoming a proficient C# developer.