Day 8: Delegates, Events, & Lambda Expressions
Welcome to Day 8. We are entering Week 2.
Yesterday, we used expressions like score => score >= 50. What exactly was that? Today, we learn about Delegates and Lambdas.
Delegates (Pointers to Methods)
A delegate is essentially a type that holds a reference to a method. It allows you to pass methods as arguments to other methods. This is fundamental for callbacks and event-driven programming.
C# provides built-in generic delegates so you almost never have to define custom ones anymore:
Func<T, ReturnType>
Used for methods that return a value. The last generic parameter is ALWAYS the return type.
// A variable that holds a method taking an int and returning a string.
Func<int, string> formatNumber;
// Assigning a method to the variable
string AddCommas(int number) => number.ToString("N0");
formatNumber = AddCommas;
// Executing it!
Console.WriteLine(formatNumber(1000000)); // "1,000,000"
Action
Used for methods that return void.
// Holds a method taking a string and returning nothing.
Action<string> printError = msg => Console.WriteLine($"ERROR: {msg}");
printError("Database connection failed!");
Predicate
A specialized Func that takes one argument and returns a bool. Used heavily in LINQ filtering!
Lambda Expressions =>
A lambda expression is simply an anonymous method (a function without a name). It allows you to define the method logic inline, exactly where it’s needed, rather than creating a separate method block.
// Traditional method assigning to a Func:
int MultiplyByTwo(int x) { return x * 2; }
Func<int, int> standardFunc = MultiplyByTwo;
// Inline Lambda (The modern way!)
Func<int, int> lambdaFunc = x => x * 2;
This is exactly how LINQ’s .Where(x => x.IsActive) works—it expects a Func<T, bool> or Predicate<T>, and you are handing it an inline method to execute against every element in the sequence!
Events
An event is a special kind of delegate heavily used in UI frameworks (like WPF or building Unity games) and reactive architectures. An object broadcasts an event, and other objects can subscribe to “listen” for it.
public class Button
{
// The Event definition
public event Action OnClicked;
public void Click()
{
Console.WriteLine("Button physically clicked!");
// Broadcast to all subscribers! (? checks for null first)
OnClicked?.Invoke();
}
}
// Subscribing!
Button submitBtn = new Button();
submitBtn.OnClicked += () => Console.WriteLine("Submitting form data...");
submitBtn.OnClicked += () => Console.WriteLine("Playing click sound effect...");
submitBtn.Click(); // Triggers both subscribers!
Challenge for Day 8
Create an Action<string, string> that takes a First Name and Last Name, and prints out the full name explicitly formatted to uppercase. Execute it using a Lambda expression.
Tomorrow: Asynchronous Programming (async / await).