Delegates in C# are types that define a method signature. They allow methods to be passed as arguments to other methods or to be assigned to variables. Delegates can be used for event handling, callback functions, and multi-casting of methods invocation. A delegate in C# is similar to a function pointer in C or C++.
But what are the common use cases for delegates?
Event handling
Delegates are often used to handle events in C#. For example, when a button is clicked, an event is raised and the event handler, which is a delegate, is invoked. This allows the developer to separate the event-handling logic from the code that raises the event.
Example:
class Button { public event EventHandler Click; public void OnClick() { Click?.Invoke(this, EventArgs.Empty); } } class Form { private Button addEmployeeBtn; public Form() { addEmployeeBtn = new Button(); addEmployeeBtn.Click += AddEmployeeBtn_Click; } private void AddEmployeeBtn_Click(object sender, EventArgs e) { Console.WriteLine("Add Employee Button was clicked!"); } }
In the example above example, the Click
event of the Button
class is defined using the EventHandler
delegate. The Form
class subscribes to the event using the +=
operator, which adds the AddEmployeeBtn_Click
method as an event handler. When the button is clicked, the OnClick
method of the Button
class is called, which raises the Click
event and invokes the event handlers, in this case, the
method.AddEmployeeBtn_Click
Callback functions
Delegates can also be used as callback functions, which allows a method to be passed as an argument to another method. This is very useful when a method needs to be invoked at a later time or when a certain condition is met. It can be used for example to do some async tasks and then call a callback function on completion.
Example:
delegate void MyCallback(); class Student { public void AddStudent(MyCallback callback) { // Do some work here callback(); } } class Program { static void Main(string[] args) { Student student = new Student(); student.AddStudent(Callback); } static void Callback() { Console.WriteLine("Callback method called invoked!"); } }
In this example, the AddStudent
method of the Student
class takes a MyCallback
delegate as an argument. The Callback
method in the Program
class matches the signature of the MyCallback
delegate, so it can be passed as an argument to the AddStudent
method. When the AddStudent
method is finished, it invokes the callback
delegate, which in this case calls the Callback
method.
The result would be:
Multi-casting
A delegate can hold a reference to multiple methods, and when the delegate is invoked, all the methods are called one after another. This is called multi-casting of delegate and allows multiple methods to be called with a single delegate invocation. This can be used for example for logging or for notifying multiple listeners about a certain event.
Example:
using System; delegate void MyDelegate(); class Program { static void Main(string[] args) { MyDelegate del = SendWelcomeEmail; del += SendBenefitsEmail; del += SendPromotionEmail; del(); } static void SendWelcomeEmail() { Console.WriteLine("Welcome to our site!"); } static void SendBenefitsEmail() { Console.WriteLine("Benefits of our site!"); } static void SendPromotionEmail() { Console.WriteLine("Promotion codes just for you!"); } }
In this example, the MyDelegate
delegate is defined to take no arguments and return void. The SendWelcomeEmail
, SendBenefitsEmail
, and SendPromotionEmail
methods match this signature, so they can be assigned to a variable of the MyDelegate
type.
The del
variable is first assigned the
method, and then later it is reassigned the SendWelcomeEmail
and SendBenefitsEmail
methods using the SendPromotionEmail
+=
operator. When the delegate is invoked ( del() – by calling it like a method, with parentheses), it invokes all the methods that it currently references in order.
The result would be:
These are just a few examples of the many use cases for delegates in programming. They are versatile features that can be used in a wide range of scenarios to improve code organization and flexibility.