C#
Delegates, Events & Lambdas
6 question(s)
What is a delegate in C#?
Beginner
A delegate is a type-safe reference to a method, letting you pass behaviour as a parameter and invoke it later. Func<>, Action<> and Predicate<> are built-in delegates.
Func<int,int> square = x => x*x;
Action<string> log = Console.WriteLine;
Console.WriteLine(square(4)); // 16
Real-world example
Passing a comparison or projection function into a sorting or LINQ method.
What is the difference between Func, Action and Predicate?
Beginner
Func<...,TResult> returns a value; Action<...> returns void; Predicate<T> is a Func<T,bool> used for tests.
Func<int,bool> isEven = n => n%2==0;
Action greet = () => Console.Write("hi");
Real-world example
Passing isEven to List.FindAll to filter numbers.
What is a closure and what is a common pitfall?
Intermediate
A closure is a lambda that captures variables from its enclosing scope. A classic pitfall is capturing a loop variable by reference so all lambdas see its final value.
var fns = new List<Func<int>>();
foreach (var i in Enumerable.Range(0,3)) fns.Add(() => i); // each captures its own i (C# 5+)
Real-world example
Building event handlers in a loop that must remember the item they were created for.
How do events differ from plain delegates?
Intermediate
An event is a delegate wrapped so external code can only subscribe (+=) or unsubscribe (-=), not invoke or overwrite it — enforcing the publisher/subscriber boundary.
public event EventHandler? Saved;
protected void OnSaved() => Saved?.Invoke(this, EventArgs.Empty);
Real-world example
A ViewModel raises a Saved event that views subscribe to, without views being able to fire it.
What causes event-handler memory leaks and how do you prevent them?
Advanced
A long-lived publisher holding a delegate to a subscriber keeps the subscriber alive. Prevent it by unsubscribing (-=), using weak event patterns, or scoping lifetimes.
source.Changed += Handler;
// later, to allow GC:
source.Changed -= Handler;
Real-world example
A screen that subscribes to a singleton service must unsubscribe on close or it never gets collected.
What is the difference between multicast delegate invocation and exception handling?
Advanced
A multicast delegate invokes subscribers in order; if one throws, later subscribers are skipped and the exception propagates. Invoke manually via GetInvocationList to isolate failures.
foreach (var d in handler.GetInvocationList().Cast<Action>())
try { d(); } catch (Exception ex) { Log(ex); }
Real-world example
Notifying many listeners where one failing listener must not block the rest.