A delegate is a type-safe function pointer—references methods matching a signature. Events wrap delegates with publish/subscribe semantics so external code cannot invoke subscribers directly—core to UI and domain notifications before DI-heavy architectures.
Delegate and Action/Func
Action<string> log = msg => Console.WriteLine(msg);
Func<int, int, int> add = (a, b) => a + b;
Action and Func are built-in generic delegate types—prefer them over custom delegate declarations for simple cases.
Events
event EventHandler<int> ScoreChanged;
ScoreChanged?.Invoke(this, 100);
Only the declaring class raises events; outsiders subscribe with += and unsubscribe with -=.
Important interview questions and answers
- Q: Delegate vs event?
A: Events restrict invocation to the owner type—prevent external callers from firing another class's callbacks. - Q: Func vs Action?
A:Funcreturns a value;Actionreturns void—both are delegate shortcuts.
Self-check
- What operator subscribes to an event?
- Why use ?. when invoking events?
Pitfall: Forgetting to unsubscribe from events causes memory leaks—always remove handlers when the subscriber outlives the publisher.
Interview prep
- Delegate vs interface?
Delegates are type-safe function pointers—great for callbacks; interfaces define broader contracts with multiple members.
- Event memory leaks?
Subscribers held by events prevent GC of the subscriber—unsubscribe when the subscriber outlives the publisher.