Read the syntax
A delegate type describes a callable signature. Assigning a compatible method or lambda produces a delegate value that can be invoked later.
Func has a return value, Action returns void, and multicast delegates invoke their subscribed methods in order. Passing a delegate lets a method accept behavior as data.
Syntax
delegate returnType DelegateName(parameters);Examples
Declaring and Using a Custom Delegate
Defining a delegate type and assigning a matching method to it.
int Add(int a, int b) => a + b;
int Multiply(int a, int b) => a * b;
MathOperation operation = Add;
Console.WriteLine(operation(3, 4)); // 7
operation = Multiply;
Console.WriteLine(operation(3, 4)); // 12
public delegate int MathOperation(int a, int b);- Defining a delegate type and assigning a matching method to it.
- A delegate type describes a callable signature. Assigning a compatible method or lambda produces a delegate value that can be invoked later.
- operation first refers to Add and prints 7. Reassigning it to Multiply makes the next call print 12; the call syntax stays the same.
Using Func<> and Action<> Instead
Most of the time, the built-in generic delegates cover what you need without declaring your own type.
Func<int, int, int> add = (a, b) => a + b;
Console.WriteLine(add(3, 4)); // 7
Action<string> logMessage = msg => Console.WriteLine($"LOG: {msg}");
logMessage("Application started");- Most of the time, the built-in generic delegates cover what you need without declaring your own type.
- A delegate type describes a callable signature. Assigning a compatible method or lambda produces a delegate value that can be invoked later.
- Func adds 3 and 4 to print 7. Action writes LOG: Application started and has no return value.
Multicast Delegates
A delegate can reference multiple methods at once, invoking all of them in order when called.
Action<string> notifyEmail = msg => Console.WriteLine($"Email: {msg}");
Action<string> notifySms = msg => Console.WriteLine($"SMS: {msg}");
Action<string> notifyAll = notifyEmail + notifySms; // combine with +
notifyAll("Order shipped");
// Email: Order shipped
// SMS: Order shipped- A delegate can reference multiple methods at once, invoking all of them in order when called.
- A delegate type describes a callable signature. Assigning a compatible method or lambda produces a delegate value that can be invoked later.
- Combining two Action delegates creates an invocation list. notifyAll calls email and SMS handlers in order, printing two lines.
Passing a Delegate as a Method Parameter
A very common pattern - accepting behavior as a parameter, similar to how LINQ methods accept lambdas.
void ProcessNumbers(List<int> numbers, Action<int> action)
{
foreach (int n in numbers)
{
action(n);
}
}
List<int> nums = new List<int> { 1, 2, 3 };
ProcessNumbers(nums, n => Console.WriteLine(n * n)); // 1, 4, 9- A very common pattern - accepting behavior as a parameter, similar to how LINQ methods accept lambdas.
- A delegate type describes a callable signature. Assigning a compatible method or lambda produces a delegate value that can be invoked later.
- ProcessNumbers invokes the supplied Action for each value. The lambda squares 1, 2 and 3, so it prints 1, 4 and 9.
Best practices
- Use the built-in Func<>, Action<>, and Predicate<> generic delegates instead of declaring a custom delegate type, unless you need a very specific, named signature
- Use delegates to pass behavior into a method (like a callback or strategy), rather than duplicating similar methods with slightly different logic
- Be aware that combining delegates with + creates a multicast delegate that invokes every referenced method in order - useful for notifications, less so for methods with return values (only the last one's result is kept)
- Prefer events (built on top of delegates) instead of a raw public delegate field when other code should be able to subscribe to, but not directly invoke or reassign, a notification
Runtime & versions
.NET runtime. Feature availability depends on the language and runtime version used by your project; consult the official reference below.
C# language reference