Skip to Content
Course content

46: Multicast Delegates

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Wait, I thought a delegate only pointed to one method? How do I actually make it point to several?

You're right that a basic delegate is a reference to a single method. But in C#, delegates are actually "multicast" by nature. This means a single delegate instance can maintain an internal list—an invocation list—of multiple methods that match the same signature.

You don't need a special kind of delegate for this; you just use the += operator to "stack" methods onto your delegate. I like to think of it as a subscription list. When you finally invoke the delegate, C# just loops through that list and calls every method you've added.

public delegate void GameEvent();

public class GameEngine
{
    public GameEvent OnBossDefeated;

    public void DefeatBoss()
    {
        Console.WriteLine("The dragon has fallen!");
        // This triggers every method currently attached to the delegate
        OnBossDefeated?.Invoke();
    }
}

// In your main program:
var engine = new GameEngine();

// We "subscribe" multiple methods to the same delegate
engine.OnBossDefeated += GivePlayerXp;
engine.OnBossDefeated += PlayVictoryFanfare;
engine.OnBossDefeated += UpdateQuestLog;

void GivePlayerXp() => Console.WriteLine("Player gained 1000 XP!");
void PlayVictoryFanfare() => Console.WriteLine("Playing triumphant trumpets...");
void UpdateQuestLog() => Console.WriteLine("Quest 'Slay the Dragon' marked complete.");

engine.DefeatBoss();

In what order do these methods run, and can I remove just one of them?

C# is predictable here: the methods are called in the order they were added. In the example above, the player gets XP first, then the music plays, then the quest updates. If you need a very specific order, just be mindful of the sequence in which you use +=.

And yes, you can remove a specific method using the -= operator. This is crucial for memory management. If you have a short-lived object subscribing to a long-lived manager's delegate, and you don't unsubscribe when that object is destroyed, the manager still holds a reference to it. That's a classic recipe for a memory leak.

// Maybe the player muted the game sounds, so we stop the fanfare
engine.OnBossDefeated -= PlayVictoryFanfare;

// Now, only XP and Quest Log will trigger
engine.DefeatBoss();

What happens if the methods I'm calling return a value? Do I get all of them back?

This is the "gotcha" that trips up almost everyone the first time. If your delegate has a return type other than void, you can still multicast it, but you will only receive the return value of the last method executed. The previous return values are simply discarded.

I'll be honest: using multicast delegates with return values is usually a bad design choice. It's confusing and leads to bugs. If you find yourself needing values back from multiple sources, you're better off using a List<T> of functions or switching to a pattern where the methods modify an object passed in as a parameter.

public delegate int Calculation();
Calculation myCalc = methodA; 
myCalc += methodB;

// If methodA returns 10 and methodB returns 20, 
// result will be 20. The 10 is gone forever.
int result = myCalc(); 



📋 Practical Task

Build a Smart Home Event Hub

Create a program that simulates a "Smart Home Hub." Define a delegate called HomeAction that takes no parameters and returns nothing. Create a HomeHub class that contains a multicast delegate of this type called OnArriveHome.

Implement three separate methods: TurnOnLights, AdjustThermostat, and UnlockFrontDoor. Each should simply print a descriptive message to the console. In your main program:

  • Attach all three methods to the hub's OnArriveHome delegate.
  • Invoke the delegate to simulate arriving home.
  • Unsubscribe the AdjustThermostat method (perhaps the user turned off "Auto-Climate" mode).
  • Invoke the delegate again to verify that only the lights and the door are being handled.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.