Type-Safe Method Pointers in C#
In C#, delegates function as object-oriented, type-safe equivalents of function pointers from C and C++. As reference types derived from System.Delegate, they hold references to specific methods. The associated method can be swapped during runtime, making delegates the core infrastructure for designing event systems and asynchronous callbacks.
Decoupling Logic with Delegates
By abstracting method execution into a delegate variable, specific behaviors can be isolated from core algorithms. This decoupling enables developers to inject, replace, or extend logic dynamically without altering the underlying system structure.
Delegate Declaration and Instantiation
Defining the Signature
A delegate type is declared using the delegate keyword. The declaration dictates the required signature—specifying the return type and input parameters—that any target method must strictly adhere to.
public delegate int Processor(string inputData);The general syntax pattern follows this structure:
delegate <ReturnType> <DelegateName> <ParameterList>Binding a Method
Once a delegate type exists, an instance is instantiated and bound to a compatible method. This binding occurs via the new keyword, passing the method name as an argument without executing it. Modern C# also supports direct assignment through method group conversion.
public delegate void Notifier(string payload);
// Explicit instantiation
Notifier screenAlert = new Notifier(DisplayOnScreen);
// Direct shorthand assignment
Notifier logAlert = RecordInLog;Built-in Generic Delegate Types
The .NET framework provides built-in generic delegates to eliminate the need for redundant custom definitions. The Func<TResult> family encapsulates methods that yield a return value, with the trailing generic type indicating the output. Variants like Func<T, TResult> accept input parameters preceding the return type. For void-returning routines, the Action family serves the same purpose, supporting zero to sixteen input arguments without producing an output.
Multicast Capabilities
Delegates possess an inherent ability to manage multiple method references simultaneously, known as multicasting. The + or += operators merge delegates into an invocation list, while the - or -= operators detach them. When invoking a multicast delegate, each bound method executes in the order it was added. Key characteristics include:
- All delegate instances fundamentally inherit from
MulticastDelegate. - For delegates returning a value, only the result of the last executed method in the invocation chain is retained.
- Adding or removing targets is handled cleanly via
+=and-=. - Binding the exact same static method multiple times yields an identical underlying delegate reference.
Notifier primaryHandler = PushNotification;
Notifier fallbackHandler = SendEmail;
// Constructing a multicast chain
Notifier broadcastHandler = primaryHandler + fallbackHandler;
// Reducing the chain
broadcastHandler -= fallbackHandler;