What are delegates in C#?
Quick Answer
A delegate is a type-safe reference to a method — effectively a function pointer with a signature. You can store methods in delegate variables, pass them as arguments, and invoke them later. Func<>, Action<> and Predicate<> are built-in generic delegates; events are built on delegates; LINQ and callbacks use them everywhere.
A delegate is a type-safe pointer to a method — it has a signature, and you can put any matching method into it, pass it around, and call it later. In practice I almost never declare my own delegate type; I use the built-in ones — Action for something returning void, Func when it returns a value, Predicate for a bool test. Delegates are multicast, so you can chain handlers with +=. Events are just a locked-down delegate where outside code can subscribe and unsubscribe but can't invoke or overwrite it. LINQ is all delegates under the hood — the lambda you pass to Where is a Func.
Declaring delegate int Transformer(int x); creates a type whose instances hold one or more methods matching int (int). Modern code rarely declares custom delegate types — it uses:
Action/Action<T,...>— returnsvoid.Func<T,...,TResult>— returns a value (last type parameter).Predicate<T>—Func<T,bool>by convention.
Key facts:
- Delegates are multicast —
+=chains methods; invoking calls them in order (forFunc, you get the last return value). - Lambdas and method groups are the usual way to create them; a lambda that uses outer variables creates a closure.
- Events are a restricted delegate wrapper: outside code can only
+=/-=, not invoke or reassign. - Common uses: LINQ predicates/projections, callbacks, strategy pattern, event handlers,
IProgress<T>.
Func<int, int> square = x => x * x;
Action<string> log = msg => Console.WriteLine(msg);
int factor = 3;
Func<int, int> scale = x => x * factor; // closure over 'factor'
var result = new[] { 1, 2, 3 }.Select(square).Sum(); // 14
// passing behaviour as a parameter (strategy)
void Retry(int times, Action work) { /* ... */ }