C# stuff nobody told you – delegate is a class! And there is a good reason for that!

Have you ever wondered why blue screens of death happen so rarely, nowadays? Of course, we can thank Microsoft for this but the way they fixed this problem is not so obvious! According to Marino Posadas (and his book Mastering C# and .Net Framework) back in 2010, Microsoft made an analysis of this topic and they came to the conclusion that the 90% (wow!) of the blue screens were caused by drivers! So, Microsoft made manufacturers to follow the Hardware Compatibility List. That somehow solved most of the problem but what with the rest 10%? Most of them was due to the…

Casting and lost pointers!

Yes, the silliest and the hardest to spot errors in the programming world. But what could Microsoft do with that? Well, for example, introduce the mechanism that will check the compatibility! Ha! That’s so easy and obvious, I should work in MS and give them a piece of advice from time to time!

C# 4.0 to the rescue!

One of the main features of C# 4 were delegates. Prior to that, we only had anonymous methods and lambda expressions. Which means rather weak control over types. Btw let me emphasize that this was the year 2010, only 8 years ago… The year I started my first job. And they introduced delegates then… Which I found so old that I was even considering not writing about them… Wow, I feel like a dinosaur again…

So what delegate is, under the hood?

If you are reading this, you probably already know that (to put it simply) delegate is an object pointing on some method. And you can pass this object to another method, so it can later call this ‘some method’. For some dinosaurs and C++ programmers, it may sound familiar. Function pointer, huh? Ha! Borrrring!
But hold on a second! What differs C# delegate from its C++ cousin is the fact that C# delegate is not only a pointer! It’s a class! (And that’s why C# is classier than C++! Hahaha! Haha! Ha! Yeah, I’m sorry, I couldn’t resist!)
So, as I mentioned, delegate is a class, and derives from MulticastDelegate (which inherits Delegate class, btw). As a side note – you cannot create a class that derives from the above two, because they are special classes.
Yeah, that’s unfair! I also wanted to make my own delegate mechanism with ‘blackjack and hookers’ (Futurama, I miss you!).

But let’s go back to the C# implementation, it might be also good… After all ?.

A delegate holds a lot of useful information, like:

  • Method’s address (yeah, let’s say – pointer)
  • Method’s parameters (both types and order)
  • Method’s returned type
  • Pointer to the list of chained methods

Thanks to the first tree elements from the above, we have a control over types safety. We will not be able to pass to a delegate method a variable that is not compatible. And we know exactly what type we expect on the return of the method.

Let’s focus on delegate’s members.

There is a lot of members we could talk about, thanks to the inheritance of MulticastDelegate and Delegate class, but let’s focus only on the most important.

  • public MethodInfo Method {get;set;} – it’s a method that delegate points to. Shortly – this method will be called when we call our delegate.
  • public object Target { get; } – it’s an instance of the class on which the delegate invokes the delegate method. If the method is static – Target will be null.
  • public sealed override Delegate[] GetInvocationList() – is a method that returns an array of methods that are ‘chained’ to our delegate. Also known as ‘invocation chain’. We will talk more about this later but for now, keep in mind that invoking a delegate’s method may be invoking more than one method.

Example, or didn’t happen!

I focused on the delegates in my previous post so today I will only show you how the invocation list works. This easy demo can be found here.
We will use the classes from my previous post, but if you didn’t read it, it’s enough to know that we have a system that (in infinitive loop) simulates reading temperature from some sensors. When the temperature is too high the system sends warnings. This time, we want to send email from Monday to Friday but at weekend we want to additionally text workers.

var wSystem = new ReactorSensorsSystem();
var isWeekend = DateTime.Now.DayOfWeek == DayOfWeek.Saturday || DateTime.Now.DayOfWeek == DayOfWeek.Sunday;
var warningHandler = new ReactorSensorsSystem.NuclearReactorWarningHandler(SendWarningEmail); //(1)
var smsWarning = new ReactorSensorsSystem.NuclearReactorWarningHandler(new Program().SendWarningSMS); //(2)

while (true)
   int temp = ReactorSensorsSystem.GetTempFromSensor(); //(3)
   if (isWeekend)
      if(!warningHandler.GetInvocationList().Contains(smsWarning)) //(4)
         warningHandler += smsWarning;
      if (warningHandler.GetInvocationList().Contains(smsWarning)) //(5)
         warningHandler -= smsWarning;

   wSystem.CheckReactorTemperature(temp, warningHandler); //(6)


(1) – we create a delegate object that points to SendWarningEmail (static method)
(2) – we create another delegate object, this time pointing at SendWarningSMS (non-static method)
(3) – we “read” temperature (random number) from the “sensors”
(4) – at weekends we check if method texting workers is attached to the delegate (which in fact means – delegate’s invocation chain). If it is not attached, we attach it in the next line. Pay attention to the fact, that warningHandler already has one method attached to it (and it was attached at the moment of creating this object).
(5) – at week days, we check if delegate’s invocation chain is free of texting method. But if this method is attached, we just remove it.
(6) – we call the method that takes delegate as a parameter.


What result do we expect?

At weekend, we want both methods to be called, one after another. The order of the calling is the same as the order we attach methods. In this situation, firstly we call SendWarningEmail and then SendWarningSMS.
At a week day, we want only a SendWarningEmail method to be called.
Let’s check the result.
At the weekend:

And at the week day:

Features image by Ben White on Unsplash

Share this: