C# Delegate

When was the last time you write code using delegate in C#? Hmm do you know what it means? To be honest, I have not used delegate keyword for years. Long time ago, when I wrote I had to google for the syntax. With the evolving of C#, we have not seen it being used in production code. But, it is important, or at least is nice, to know what it is.

Years ago, when I read about it, I did not understand at all. I could not wrap it up in my head. Therefore, I avoided to use it. Maybe because I did not understand the why behind the keyword.

Time flies. I am reading C# fundamentals again. Luckily, with 10 years of experience, I can understand the delegate keyword, not that bad.

Here is the official document from MS Doc. However, I would suggest you to read from Jon Skeet.

Such a definition might cause confusion and hard to understand. One way to understand a new concept is to map it with what we have known. I hope you can have your own mapping.

Let’s explore some examples to understand delegate. Imagine a context where there is a team which has a team leader and some developers. There are some bugs need to fixed in a week. The team leader has the responsibility of leading the team to finish the mission.

The example might confuse you because, well, it is an imaginary context. In the real life, or real project modeling, things are so much complicated. The main point is a playground to write some code with delegate, forget about all new fancy stuffs such as Action, Func, inline method, or expression.

Wire up a very simple .NET Core project using VS Code, here the first version I got (after some failing builds with first time using VS Code on Mac)

using System;
using System.Collections.Generic;
namespace funApp
{
    
    delegate void KillBug(Bug bug);
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello Team Leader");
            var tl = new TeamLeader();
            tl.StartSprint(new List<Bug>{
                new Bug("Fix homepage layout"),
                new Bug("Timeout exception when searching")
            });
            tl.RunSprint(new KillBug(SayBugName));
            
            Console.Read();
        }
        private static void SayBugName(Bug bug)
        {
            Console.WriteLine($"Hi {bug.Name}, how are you today?");
        }
        
    }
    class TeamLeader
    {
        private IList<Bug> _bugs = new List<Bug>();
        public void StartSprint(IList<Bug> bugsFromBacklog)
        {
            foreach (var bug in bugsFromBacklog)
            {
                _bugs.Add(bug);
            }
        }
        public void RunSprint(KillBug knowHowToKillBug)
        {
            foreach (var bug in _bugs)
            {
                knowHowToKillBug(bug);
            }
        }
    }
    class Bug
    {
        public string Name { get; set; }
        
        public Bug(string name)
        {
            Name = name;
        }
    }
}

It works.

The example demonstrates a very important concept in programming: Separation of Concern. Looking at the RunSprint method for a moment. A team leader usually does not know how to kill a bug, I know many team leaders are great developers, but they cannot kill all bugs themselves. They usually use ones who know how to kill a bug, which is usually a developer in his/her team. Or he can outsource to others, as far as they know how to kill a bug. That “know how to kill a bug” is modeled via a delegate “KillBug”.

In later version of C# (2, 3,..) and .NET, there are more options to rewrite the code to get rid of KillBug delegate declaration. But the concept remains.

       public void RunSprint(Action<Bug> knowHowToKillBug)
        {
            foreach (var bug in _bugs)
            {
                knowHowToKillBug(bug);
            }
        }

That method will produce the same outcome.

Do I need to know delegate to write C# code, to finish my job? No. You don’t.

Do I need to understand it? Yes. You should. Understanding the why behind the delegate concept is very important to make a proper design. Every feature has a good reason. We, developers, must understand that reason to make the best use.

Write a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.