Delegates in C# are powerful constructs that act as type-safe function pointers. They provide a way to pass methods as parameters, enabling flexible and reusable code designs.
A delegate is a type that represents references to methods with a particular parameter list and return type. They allow methods to be passed as parameters, stored as variables, and invoked dynamically.
To declare a delegate, use the delegate
keyword followed by the method signature:
public delegate int MathOperation(int x, int y);
Once declared, you can create delegate instances and assign methods to them:
public static int Add(int a, int b) { return a + b; }
public static int Subtract(int a, int b) { return a - b; }
MathOperation addDelegate = Add;
MathOperation subtractDelegate = Subtract;
int result1 = addDelegate(5, 3); // result1 = 8
int result2 = subtractDelegate(10, 4); // result2 = 6
C# delegates support multicasting, allowing multiple methods to be invoked through a single delegate instance. This feature is particularly useful for implementing event handling systems.
public delegate void Notifier(string message);
Notifier notifier = Console.WriteLine;
notifier += (msg) => Console.WriteLine($"Log: {msg}");
notifier("Hello, delegates!"); // Invokes both methods
C# provides several built-in delegate types for common scenarios:
Action
: For methods that don't return a valueFunc
: For methods that return a valuePredicate
: For methods that return a booleanThese generic delegates reduce the need for custom delegate declarations:
Action<string> print = Console.WriteLine;
Func<int, int, int> add = (a, b) => a + b;
Predicate<int> isEven = (num) => num % 2 == 0;
Delegates work seamlessly with lambda expressions, enabling concise inline method definitions:
Func<int, int, int> multiply = (x, y) => x * y;
int product = multiply(4, 5); // product = 20
Delegates are a cornerstone of C#'s functional programming features. They provide a bridge between object-oriented and functional paradigms, enabling more flexible and modular code designs.