C#
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Object-Oriented C#
-
Section 4: Working with Data
-
Section 5: Error Handling
-
Section 6: Delegates and Events
-
Section 7: Async Programming
-
Section 8: More Language Features
-
Section 9: File I/O and Serialization
-
Section 10: Networking in .NET
-
Section 11: The .NET Ecosystem
-
Section 12: Memory and Performance
-
Section 13: Concurrency Beyond Async
-
Section 14: Reflection and Attributes
-
Section 15: Testing and Best Practices
-
Section 16: Design Patterns in C#
-
Section 17: Standard Library Deep Dive
-
Section 18: Data Structures and Algorithms in C#
-
Section 19: GUI and Desktop Development Overview
-
Section 20: Practical Projects
-
Section 21: More Practice Exercises
-
Section 22: More Standard Library and Text Processing
-
Section 23: More Design Patterns
-
Section 24: More Projects
-
Section 25: Interview Practice
-
Section 26: C# Keywords Reference (Modifiers)
-
Section 27: C# Keywords Reference (Statements)
-
Section 28: C# Keywords Reference (Operators)
-
Section 29: BCL: System.Collections.Generic
-
Section 30: BCL: System.Linq
-
Section 31: BCL: System.Threading
-
Section 32: BCL: System.IO
-
Section 33: BCL: System.Text and System.Text.Json
-
Section 34: BCL: System.Net.Http
-
Section 35: C# Language Specification Topics
-
Section 36: More Practice Exercises
-
Section 37: More Async Patterns
-
Section 38: More BCL: System.Reflection and System.Diagnostics
-
Section 39: Nullable Reference Types In Depth
-
Section 40: C# Records and Pattern Matching In Depth
-
Section 41: Dependency Injection Deep Dive
-
Section 42: More Interview and Whiteboard Practice
46: Multicast Delegates
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
OnArriveHomedelegate. - Invoke the delegate to simulate arriving home.
- Unsubscribe the
AdjustThermostatmethod (perhaps the user turned off "Auto-Climate" mode). - Invoke the delegate again to verify that only the lights and the door are being handled.
There are no comments for now.