Delegates in c#
April 08, 2020

Delegates in c# is a concept which confuses some developers, if you fall into this category, worry not this article is meant to answer the following questions:

  1. what are delegates?
  2. why do I need to use delegates?
  3. How to use delegates.

What are delegates?

Delegate is a reference type to methods in c#. It’s like a pointer to a function. it holds the reference of a method.

With delegates you can do the following;

  • Call All Methods attached to the delegates at once whenever the delegate is called.
  • Add more methods to delegates at runtime
  • Remove existing methods Added to delegates at runtime

After I give the above answer I often get the following question how are delegates different from nested function calls? Delegate is different from nested function calls because it enables us to add or remove methods to the delegate to be executed at run time.

Why do we need to use delegates

  • Open Closed Principle: this means open for extension and closed for modification. delegates ensure once you implement your method, you can add more functionality to such a method without refactoring such a method. All you need to do is to add more methods to the delegate handler.
  • Pass Methods as parameters to other methods i.e. Callbacks in c#
  • You want to call two or more methods, same in signature but reside in different classes at the same time whenever something happens.
  • Cleaner Architecture

How To Use Delegates

I’ll show a real-world example of where we might consider using delegates. You might want to report the health status of your application. and you want the following to happen whenever the report is provided.

  1. Log the health status in a file.
  2. Send an email containing the health status to your admin.
  3. Send an SMS containing the health status to the admin.

All the above at the same time.

1private delegate void OnReport(string Message);
2 private OnReport _onReport;

from the above, we declare our delegate using the delegate keyword.

1public void AddReportHandler(Action<string> action){
2 _onReport += new OnReport(action);
3 }

We added the Handler which is used to add more More methods to our delegates.

Note the parameter type of the handler is of type Action. this parameter type could be of type Func. These are known as generic delegate types.

The primary difference between Action and Func is that Action is used for method signatures that return a void, while Func is used for method signatures that have a return value.

1public void Report(string healthStatus) {
2 if(_onReport != null) {
3 _onReport(healthStatus);
4 }
5 }

We declare a single method Report, which would execute all functions appended to the delegate.

Here is the full implementation

1using System;
2
3class MainClass {
4 static public void Main(String[] args)
5 {
6 var appHealth = new HealthMonitor();
7
8 appHealth.AddReportHandler(message => {
9 Console.WriteLine($"Logging app health status on a file Logic - {message}");
10 });
11 appHealth.Report("healthy"); //prints to file and sends mail logic executes
12 appHealth.RemoveAllReportHandler(); //we remove all added functions
13 appHealth.Report("Not healthy"); // output will be empty here
14 }
15}
16
17public class HealthMonitor{
18 public HealthMonitor() {
19 Email(); //Add append email sending logic to the delegate
20 }
21
22 private delegate void OnReport(string Message); //declare the delegate
23 private OnReport _onReport;
24
25 public void AddReportHandler(Action<string> action){
26 _onReport += new OnReport(action);
27 }
28
29 // will remove all method appended to the delegate when called
30 public void RemoveAllReportHandler(){
31 _onReport = null;
32 }
33
34 public void Email() {
35 this.AddReportHandler(message =>
36 Console.WriteLine($"Logging app health status via email - {message}"));
37 }
38
39 public void Report(string healthStatus) {
40 if(_onReport != null) {
41 _onReport(healthStatus);
42 }
43 }
44}

You can choose to Run the code on Repl.it


Written by Adeyemi Adekorede
You can follow him on Twitter