In this tutorial, written for beginning programmers, I’d like to show a little demonstration on the usage of delegates and how we can go all crazy by refactoring and magically see all our duplicate code disappear.

Imagine we are writing the next ultimate Command&Conquer spinoff which can run on any computer …in console-mode. Now imagine that in the early phases of our prototype we create a Soldier class: all soldiers should be able to simply “Do their thing” when asked to do so. When they do, they should report on what they do, of course. Typical “DoYourThing” actions might include throwing a grenade, cowardly running away or going into Full Rambo-mode:

Phase 1: Oldschool coding

Smart as a cookie, we create our Soldier class:

class Soldier { public Soldier(string name) { Name = name; } public string Name { get; set; } public virtual void DoYourThing() { //Let the inherited soldiers do their thing } }

Look how smart. We made our DoYourThing() method virtual, allowing us to create an over-the-top amount of Soldier child classes that all override the method with the specific action that Soldier can do.

Mmm…but all these inherited classes (GrenadeSoldier, RamboSoldier, etc.) are blowing out of proportion and contain 99% duplicate code.

Phase 1.2 or 1.1

Depending on your train of thought, you might first have done this step or first the previous one and then this one. Anyhow, let’s be a smarter cookie and don’t go for inheritance and simply write a switch:

class Soldier { public Soldier(string name, int actionin) { Name = name; ActionNumber = actionin; } public string Name { get; set; } public int ActionNumber { get; private set; } public virtual void DoYourThing() { switch(ActionNumer) { case 1: Console.WriteLine(Name + ":Thowing a grenade."); break; //.. } } }

Again, we’ll ignore the obvious improvement of making this ActionNumber into an enum, but as you might have guessed, this still ain’t the right way.

Phase 2: On with the delegates

Since this tutorial about delegates, let’s try to refactor our code so that delegates start showing their worth.

It’d be much handier if we could keep the implementation of the different actions a soldier can do outside the Soldier class itself. Imagine that in a future update of your game you’d like to add new cool soldiers and/or their actions, if we keep the everything tightly bound (i.e. keep the actions inside the soldier) we’d have to recompile our entire Soldier class. So, out with the Soldier actions, in with delegates!

public delegate void SoldierAction(); class Soldier { public Soldier(string name, SoldierAction actionin) { Name = name; Action = actionin; } public string Name { get; set; } public SoldierAction Action { get; private set; } public virtual void DoYourThing() { Action(); } }

So we defined a new SoldierAction delegate which we’ll use as our vehicle to ‘give’ the action-implementation to the soldier. Notice that we basically changed the type of our ActionNumber from int to the newly creates SoldierAction delegate type (and gave it a slightly improved name).

Imagine now that we moved the different actions to self-contained methods, outside the Soldier class:

public static void RamboStyle() { Console.WriteLine("Kill'm all!"); }

We now can create cute little Rambo’s and other types that will do the actions they were made for:

Soldier rambo = new Soldier("John", new SoldierAction(RamboAction)); rambo.DoYourThing();

Notice that IntelliSense (or is it Resharper?) is kind enough to point out that we could also write:

Soldier rambo = new Soldier("John", RamboAction);

For all you lambda lovers out there: suppose every action will be totally different and writing a method for each action would be overhead, we could also write:

Soldier rambo = new Soldier("John", () => {Console.WriteLine("Come get some");});

Phase 3: Enter Action<T>

In the previous refactor, we explicitly defined a new delegate type:

public delegate void SoldierAction();

Thanks to the more generic Func/Action delegates, we can remove that line in its entirety. Basically, Func and Action are generic, parameterized delegates. Their main reason for existence is simply to remove lines like the one just mentioned in which we explicitly define a new delegate.

First, let’s see what the main difference is between Func and Action:

Func delegates are used to encapsulate methods that return a value .

delegates are used to encapsulate that . Action delegates are used to encapsulate methods that return void.

Now, being the lazy bum that I am: check out this excellent tutorial on the basics of both Func and Action delegates. I can’t explain it any better than they do, so hop to that site, read it all and come back here. I can wait.

Since our soldier actions return void, we’ll go for the Actiondelegate. However, because no parameters are provided we can use the non-generic one. Our refactored class becomes (and we delete the SoldierAction delegate definition):

class Soldier { public Soldier(string name, Action actionin) { Name = name; Action = actionin; } public string Name { get; set; } public Action Action { get; private set; } public virtual void DoYourThing() { Action(); } }

Note that we don’t have to change anything in the way we need to instantiate new Soldier objects.

Phase 4: Bring in the soldiers

With this done. We can now create vast armies of soldiers doing their thing:

var soldiers = new List<Soldier>() { new Soldier("Joey", CowardAction), new Soldier("Carnie", GrenadeThrowerAction), new Soldier("John", RamboAction), }; foreach (var soldier in soldiers) { soldier.DoYourThing(); }

Immediately our duplicate code alarm goes into overdrive. Now what? Well, just for the sake of completeness. Let’s try to make those 3 lines in which we add new soldiers shorter, because, be honest, they are 90% identical (don’t start calculating this percentage please).

Let’s wrap the ‘action’ of creating new soldiers and putting them in our list into…you’ll never guess it….Wait for it. ..Yup, let’s wrap it into an Action delegate! And for the sake of being ubercool (hey we are writing C&C after all), we’ll add in some samba…I mean lambda flavour!

Action<string, Action> fastSoldierMaker = (name, action) => soldiers.Add(new Soldier(name, action)); fastSoldierMaker("Joey", CowardAction); fastSoldierMaker("Carnie", GrenadeThrowerAction); fastSoldierMaker("John", RamboAction);

Now, to be honest. This last example was mainly introduced to show how we can define generic delegates: we simply state what parameters the delegate methods accept (string, Action in our case) and we’re done; no need to define a new delegate type first.

Phase 5: Barracks to do the hard work

How could we use our new fastSoldierMaker delegate? Imagine we have several Barracks, each which creates a specific type of soldier. We could pass the fastSoldierMaker to each barrack when it is constructed: each created soldier will automatically be added to our full list soldiers:

class Barrack { public void MakeUnit() { if (BuildAction != null) { BuildAction("somedude", TypeOfSoldiers); } } public Action<string, Action> BuildAction { get; set; } public Action TypeOfSoldiers { get; set; } }

I leave it up to you to create a nifty random name generator for each soldier.

Next, we can now do something like:

var soldiers = new List<Soldier>(); Action<string, Action> fastSoldierMaker = (name, action) => soldiers.Add(new Soldier(name, action)); var cowardCreatorBarrack = new Barrack() {BuildAction = fastSoldierMaker, TypeOfSoldiers = CowardAction }; cowardCreatorBarrack.MakeUnit();

Phase 5.1: Refactoring barracks to add some Func

Did you just see what I did there? Funny huh. *cough* As one of my reviewers kindly pointed out: a) my barracks could do a bit more work, resulting in less work on the outside, and b) I haven’t shown how the generic Func delegate can be used.

Imagine we create a Func delegate inside the barracks which we’ll use to create a soldier with a given name. We can than afterwards change, for example, the type of soldier to create.

private Func<string, Soldier> createUnitFunction;

What we state here is that the createUnitFunction is a delegate for any method that accepts one string parameter and returns a Soldier.

Next stop, we’ll add a nice constructor to which we’ll pass the type of soldier to create and the list to which the created soldier should be added to. Resulting in (thanks Hannes Lowette from Axxes):

class Barrack { private Func<string, Soldier> createUnitFunction; public Barrack(ICollection soldiers, Action typeOfSoldier) { Soldiers = soldiers; TypeOfSoldier = typeOfSoldier; createUnitFunction = (name) => (new Soldier(name, TypeOfSoldier)); } public Action TypeOfSoldier { get; private set; } public ICollection<Soldier> Soldiers { get; private set; } public void MakeUnit() { if (createUnitFunction != null) { Soldiers.Add(createUnitFunction("somedude")); } } }

We can then simplify our soldier creating code:

var soldiers = new List<Soldier>(); var cowardCreatorBarrack = new Barrack(soldiers, CowardAction); cowardCreatorBarrack.MakeUnit();

Conclusion

So, that’s it for now. Hope you’ve felt a bit of ‘the force’ of using delegates and their more modern generic counterparts. (yeah, I don’t like to write conclusion… they tend to repeat what was said before).

A special thanks to Glenn Ergeerts (Artesis) and Hannes Lowette (Axxes) for reviewing this.