C# - Delegates 101 - A Practical Example

A practical example not too simple, not too complex, to explain delegates

This article has completely been reviewed, thanks to many encouraging comments below.

Introduction

Delegates play a major role in C# (e.g. LINQ's lambda expressions), so it's a good idea to really understand them.

Luckily, you'll find a whole bunch of well written articles on CodeProject that explain delegates (see links at the end). But IMHO, most articles fail to include a good example. Either they are too simple or too complex.

In this article, I'll try to give a practical example, albeit not from the real coding world.It's meant to give you a *feel* of how and when to use delegates.Still, the code will execute!

Delegates Simplified Recap

All you C# buffs will excuse me if I give a quick recap of delegates, and oversimplify things while doing so.

First off, a delegate is a type, i.e. a class. It’s a special class (you'll see why in a sec), but still, it's just a class.That means that like any other class, in order to be used, it must be:

declared and

instantiated

This will result in an object. That object can then be:

invoked

These are the 3 main steps in the lifecycle of a delegate. I'll point them out in the code.

Episode 1 – Without Delegates: the MarketingDepartment and its Service Providers

Suppose you have a class, called MarketingDepartment. It's job is to run advertising campaigns on new prospects (class CustomerAddress).If the budget is less then 10000, only Ballpens will be sent to the prospects. If we can afford more, we'll send coffee cups!

In order to do that, MarketingDepartment has 3 different "service providers" : an AddressProvider that will provide addresses, a BallpenCompany that will send the ballpens, and a CoffeeCupCompany that... well, you get the idea !

The Program class is the starting point. CustomerAddress is the class we'll use to pass addresses of prospects.The real shabang goes on in the MarketingDepartment: we'll fetch the adresses, and send those to the BallpenCompany or the CoffeeCupCompany, depending on the given budget.

Episode 2 – Enter the Delegate: Tell the AddressProvider How to Proceed!

The Marketing people, smart as they are, have an idea to speed things up! They say: "Hey, we don't want to waste time getting the addresses back from the AddressProvider and then send them to the BallpenCompany or the CoffeeCupCompany. Instead, it would save time if the AddressProvider knows immediately what to do with the addresses." />

In short, this is the strategy to follow:

A public delegate is declared, that will serve as the wrapper of the method that has to be invoked

The MarketingDepartment will fill that wrapper with the method of its choice (SendBallpens or SendCoffeeCups), and pass the wrapper to AddressProvider

The AddressProvider will accept the wrapper, and invoke it, without even knowing what concrete method is being executed

Here's how it would look like in code (I have cut out the bits that didn't change)

// here is the DECLARATION of the delegate (Step 1)
// the delegate class name is "DoAfterGetAddresses"
// it must specify the signature of the methods it will represent :
// the return type (bool in this case, can be any type, or "void")
// and optionally the parameters (in this case : List<CustomerAddress>)
publicdelegatebool DoAfterGetAddresses(List<CustomerAddress> ListOfAddresses);
publicclass MarketingDepartment
{
publicbool ExecuteNewCampaign(decimal budget)
{
bool success = false;
AddressProvider MyAddressProvider = new AddressProvider();
// here I will declare a delegate object of the delegate type above
// I will not instantiate it yet, because that depends on the budget
DoAfterGetAddresses ToDoAfterAddresses;
if (budget < 10000)
{
BallpenCompany MyBallpenCompany = new BallpenCompany();
// here I'll instantiate the delegate object (Step 2)
// I need to assign a method with the same signature as declared
// Also notice that I don't need to give the parameter yet
ToDoAfterAddresses = MyBallpenCompany.SendBallPens;
}
else
{
CoffeeCupCompany MyCoffeeCupCompany = new CoffeeCupCompany();
//same here
ToDoAfterAddresses = MyCoffeeCupCompany.SendCoffeeCups;
}
// it's now time to let the AddressProvider handle the campaign
// note how we pass the delegate instance as a parameter
success = MyAddressProvider.HandleCampaign(ToDoAfterAddresses);
return success;
}
}
publicclass AddressProvider
{
//here's the method that accepts the delegate object as parameter
publicbool HandleCampaign(DoAfterGetAddresses ToDoAfterAddresses)
{
bool success = false;
//get the addresses first
List<CustomerAddress> ListOfAddresses = GetAddressesNewProspects();
//now invoke the delegate (Step 3)
//at this stage, the ListOfAddresses is needed to pass as argument
success = ToDoAfterAddresses(ListOfAddresses);
// this means that the AddressProvider does NOT know what method
// exactly has been called : MyBallpenCompany.SendBallPens
// or MyCoffeeCupCompany.SendCoffeeCups
// that was the decision of the MarketingDepartment
// Furthermore, the signature tells me that the
// delegated method will return a boolean,
// that I can return that to the MarketingDepartment
return success;
}
public List<CustomerAddress> GetAddressesNewProspects()
{
....
}
}

Conclusion

A delegate turns out to be a sort of an interface of a method of an object -- ANY method of ANY object that meets its signature.

The delegate object can then be passed around as a parameter, and invoked by the receiving object.

In UML, I don't know (yet) how a delegate is diagrammed, but this is my best shot (better suggestions are welcome!)

Episode 3 – Another Scenario: Delegates that Tell the MarketingDepartment How to Proceed!

Another scenario would be that the AddressProvider has a connection with a BallpenCompany and a CoffeeCupCompany, as the UML class diagram shows.Instead of exposing those companies to the MarketingDepartment, the AdressProvider makes 2 delegates available: one for sending ballpens, another for sending coffee cups.

Conclusion

Delegates are a cornerstone for a significant portion of the C# language, especially the event-framework. Yet, they have a right on their own to be used in code. So, it's worth spending some time trying to understand them as completely as possible.Although there are many well-written articles available (see links below), most of them in my humble opinion lack a practical example that is neither too simple nor too complex.This article tried to fill that gap. I hope it succeeded somewhat in achieving that goal.

Links

These are articles I learned a lot from. Some of them are even fun to read!

Share

About the Author

I'm a self-made developer. And after years of writing code, I think I don't suck at everything ! When I stumble on a problem, I can't help but to figure it out. In some cases, I even write an article about it !
Also, in my quest to write better code, I have obtained a certificate as UML Professional, and I'm also a Certified ScrumMaster.

Your writing style is perfect! Content is perfect! And from the comments I'd have to say your attitude is perfect as well. You take criticism well and that is a commendable trait from a teacher. Vote 5

I think you wrote this article because you (at some point before) have mastered this subject but it was not easy. After mastering it you were then able to peer into the possibilities of it, and how it would improve the elegance of your future solutions. But most of all, because it's such a tough subject for new developers, you want all of them to have what you have - a good appreciation of this topic. That's the feel I get from reading [most of] your article. I couldn't finish it because A) I already know this stuff and B) it's just far too long (still). Ironically, I think you did the thing you set out not to do. You over complicated the message of the article with too much material. I would rate you off the scale (excellent +++) for all other aspects apart from this. Pretend you know nothing about delegates and read it yourself and you will see. By the way - I had no clue that English was not your first language. Your writing style is excellent. I think the American chap was genuinely amused at your 'waste' vs 'waist' mistake. I think he was trying to share the joke with you rather than pulling you up for it. As an Englishman, it's my god-given right to have the rest of the world communicate with me in my own language. What makes the rest of the world accomplished, and therefore shows me to be less so, is that, as demonstrated by your mastery, they do it so well. Nice work. Well done.

Gosh. Wow.
You certainly know how to mix sour and sweet !
Thanks for the compliments, and "ouch" for the remarks.
But I take them positively. If I have some time the coming days, I will review the article and try to make it less complicated.
The thing is, when you try to explain delegates, a certain level of abstraction is required. If an example is too simple, people say : "Why bother ? I can write that without delegates !". Well, that was my reaction anyway. I have used delegates only when the business or program logic practically forced me to use them, and I wanted to show that in an example.
But as you pointed out, this can probably be done even more simple, and I'll have a look at it.
A big thanks for your input, and BTW I never made a big deal of the "waist-waste" thing, I reacon it was just funny for you +350,000,000 native English speakers !

I think you should review it if you can and here's why. You impart your knowledge (in your writing style) so well, that if the article were more concise, it would be a light-bulb moment for some poor chap/chapess struggling with this subject. Which was obviously your goal anyway. What you say about 'explaining delegates' is true, but it's true of most tech topics. The trick is in the example you pick. Pick the right example, and that article would make someone really glad you wrote it. Kind regards.

To those who do not know the in and outs of C#'s delegates this is a very good explanation of them. Its a little long, and although a practical example its a little complicated, which is why it got 4 instead of 5. Other that that though its a good article.

Also to the Comment about the sentence. It would be "we don't want to waste time...".

Hi Josh
First off, thanks for your input !
1. You say I'm using too much code and text to explain something simple... Well, that depends on how you look at it. I guess for advanced physics students, E = mc2 is crystal clear, but when you try to explain that to 1st graders, it takes a little bit more effort. That's what my article is all about.
2. About the snippet "we don't wanna waist time"... Indeed, English is not my native language. So I would be very happy if you could provide an actual correct sentence !