C# provides robust features for handling function references and event-driven programming. Three fundamental concepts—Delegates, Events, and Lambda Expressions—work in tandem to create flexible, reusable, and efficient code. These topics frequently appear in C# technical interviews, making them essential for every developer to master. This blog explores these crucial C# interview topics in detail.
We will break down Delegates, Events, and Lambda Expressions, explain their individual roles, and demonstrate how they integrate for real-world applications.
A delegate is a type that holds references to methods with a matching signature, enabling function pointers, callbacks, and event handling in C#.
A delegate is defined using the delegate keyword.
public delegate void MyDelegate(string message);
This defines a delegate type that refers to any method with a void return type and a string parameter.
class Program
{
static void ShowMessage(string message)
{
Console.WriteLine("Message: " + message);
}
static void Main()
{
MyDelegate del = new MyDelegate(ShowMessage);
del("Hello, Delegates!"); // Output: Message: Hello, Delegates!
}
}
Delegates can reference multiple methods. When invoked, all methods in the invocation list execute.
void Method1(string msg) => Console.WriteLine("Method1: " + msg);
void Method2(string msg) => Console.WriteLine("Method2: " + msg);
MyDelegate del = Method1;
del += Method2;
del("Test");
// Output:
// Method1: Test
// Method2: Test
Events are built on delegates and provide a structured way to implement the observer pattern. Events ensure that subscribers can add or remove handlers without directly invoking them.
An event is declared using the event keyword with a delegate type.
public delegate void Notify();
class Process
{
public event Notify OnProcessCompleted; // Declare event
public void Start()
{
Console.WriteLine("Process Started...");
OnProcessCompleted?.Invoke(); // Raise event if subscribers exist
}
}
class Program
{
static void ShowMessage()
{
Console.WriteLine("Process Completed Successfully.");
}
static void Main()
{
Process process = new Process();
process.OnProcessCompleted += ShowMessage; // Subscribe
process.Start();
}
}
Events prevent external invocation.
They enforce one-way communication (only publishers can raise them).
They provide better encapsulation and maintainability.
Lambda expressions offer a concise way to define inline functions, often used in LINQ, event handling, and functional programming.
A lambda expression follows this syntax:
(parameter) => expression
Example:
Func<int, int> square = x => x * x;
Console.WriteLine(square(5)); // Output: 25
Instead of defining a separate method, we can use a lambda expression:
MyDelegate del = msg => Console.WriteLine("Lambda: " + msg);
del("Hello");
Lambdas simplify event subscriptions:
process.OnProcessCompleted += () => Console.WriteLine("Lambda: Process Finished!");
Events depend on delegates to notify multiple subscribers.
public delegate void ProcessEventHandler(string status);
class Process
{
public event ProcessEventHandler ProcessCompleted;
public void Start()
{
Console.WriteLine("Process Started...");
ProcessCompleted?.Invoke("Success");
}
}
class Program
{
static void Main()
{
Process process = new Process();
process.ProcessCompleted += status => Console.WriteLine("Process ended with status: " + status);
process.Start();
}
}
Lambdas reduce unnecessary method declarations.
Without lambda:
void ShowStatus(string status)
{
Console.WriteLine("Process ended with: " + status);
}
process.ProcessCompleted += ShowStatus;
With lambda:
process.ProcessCompleted += status => Console.WriteLine("Process ended with: " + status);
In Windows Forms and WPF, events are crucial for UI interactions.
Button btn = new Button();
btn.Click += (s, e) => Console.WriteLine("Button Clicked!");
Here:
The Click event uses a delegate.
A lambda expression simplifies the subscription.
Delegates allow method references and enable callbacks.
Events provide a structured way to notify multiple subscribers.
Lambda Expressions simplify delegate and event usage.
They work together to enable event-driven programming and clean, maintainable code.
Mastering Delegates, Events, and Lambda Expressions is essential for C# interviews and real-world applications. These concepts promote flexibility, modularity, and responsiveness in software design. Make sure to practice coding examples, as these topics are frequently covered in C# interview topics.