Mastering Action and Func Delegates in C#: Real-World Patterns and Examples

In C#, delegates like Action and Func allow you to treat behavior as data — meaning you can pass methods around like variables. This concept is powerful and opens doors to cleaner, more flexible, and decoupled code. In this article, we’ll explore: What Action and Func are How to use them effectively Real-world examples using design patterns like Strategy and Command What Are Action and Func in C#? Action Delegate Represents a method that returns void. Can take 0 to 16 input parameters. Action greet = name => Console.WriteLine($"Hello, {name}!"); greet("Alice"); // Output: Hello, Alice! Func Delegate Represents a method that returns a value. Can take 0 to 16 input parameters, last type is the return type. Func add = (a, b) => a + b; int sum = add(3, 4); // sum = 7 Why Use Action and Func? Decouple logic from implementation. Useful in LINQ, event handling, callbacks, dynamic method binding. Helps implement design patterns with less boilerplate. Real-World Example 1: Strategy Pattern Using Func The Strategy Pattern allows you to swap algorithms dynamically. Let’s build a tax calculator that can apply different tax strategies using Func. Real-World Example 1: Strategy Pattern Using Func The Strategy Pattern allows you to swap algorithms dynamically. Let’s build a tax calculator that can apply different tax strategies using Func. public class TaxCalculator { private readonly Func _taxStrategy; public TaxCalculator(Func taxStrategy) { _taxStrategy = taxStrategy; } public decimal Calculate(decimal amount) => _taxStrategy(amount); } Usage var standardTax = new TaxCalculator(amount => amount * 0.2m); Console.WriteLine(standardTax.Calculate(100)); // Output: 20 var reducedTax = new TaxCalculator(amount => amount * 0.1m); Console.WriteLine(reducedTax.Calculate(100)); // Output: 10` Why It's Clean No need for multiple strategy classes. Easily inject behavior via Func. Real-World Example 2: Command Pattern Using Action The Command Pattern encapsulates a request as an object. Let’s create a simple remote control that executes commands using Action. public class RemoteControl { private readonly Action _command; public RemoteControl(Action command) { _command = command; } public void PressButton() => _command(); } Usage var turnOnLight = new RemoteControl(() => Console.WriteLine("Light On")); turnOnLight.PressButton(); // Output: Light On var playMusic = new RemoteControl(() => Console.WriteLine("Music Playing")); playMusic.PressButton(); // Output: Music Playing Advantage You can queue commands, undo, or log them — all using Action. Combining Action and Func: Workflow Example Let’s simulate a data processing pipeline: Func fetchData = () => "raw data"; Func processData = data => data.ToUpper(); Action saveData = result => Console.WriteLine($"Saved: {result}"); var raw = fetchData(); var processed = processData(raw); saveData(processed); // Output: Saved: RAW DATA *Final Thoughts : * Understanding and leveraging Action and Func can simplify your code, especially when implementing common patterns. They enable dynamic, reusable behaviors that are perfect for modern C# development. Next time you’re about to create multiple strategy or command classes, consider whether delegates can do the job with less overhead. References Official Microsoft Docs - Delegates C# Action Delegate C# Func Delegate GitHub Repo: MakeUseOfActionAndFuncDelegate

Mar 20, 2025 - 10:13
 0
Mastering Action and Func Delegates in C#: Real-World Patterns and Examples

In C#, delegates like Action and Func allow you to treat behavior as data — meaning you can pass methods around like variables.

This concept is powerful and opens doors to cleaner, more flexible, and decoupled code.

In this article, we’ll explore:

  1. What Action and Func are
  2. How to use them effectively
  3. Real-world examples using design patterns like Strategy and Command

What Are Action and Func in C#?

Action Delegate
Represents a method that returns void.
Can take 0 to 16 input parameters.

Action greet = name => Console.WriteLine($"Hello, {name}!");
greet("Alice"); // Output: Hello, Alice!

Func Delegate
Represents a method that returns a value.
Can take 0 to 16 input parameters, last type is the return type.

Func add = (a, b) => a + b;
int sum = add(3, 4); // sum = 7

Why Use Action and Func?

Decouple logic from implementation.
Useful in LINQ, event handling, callbacks, dynamic method binding.
Helps implement design patterns with less boilerplate.

Real-World Example 1: Strategy Pattern Using Func
The Strategy Pattern allows you to swap algorithms dynamically.

Let’s build a tax calculator that can apply different tax strategies using Func.

Real-World Example 1: Strategy Pattern Using Func
The Strategy Pattern allows you to swap algorithms dynamically.

Let’s build a tax calculator that can apply different tax strategies using Func.

public class TaxCalculator
{
    private readonly Func _taxStrategy;

    public TaxCalculator(Func taxStrategy)
    {
        _taxStrategy = taxStrategy;
    }

    public decimal Calculate(decimal amount) => _taxStrategy(amount);
}

Usage

var standardTax = new TaxCalculator(amount => amount * 0.2m);
Console.WriteLine(standardTax.Calculate(100)); // Output: 20

var reducedTax = new TaxCalculator(amount => amount * 0.1m);
Console.WriteLine(reducedTax.Calculate(100)); // Output: 10`

Why It's Clean
No need for multiple strategy classes.
Easily inject behavior via Func.

Real-World Example 2: Command Pattern Using Action
The Command Pattern encapsulates a request as an object.

Let’s create a simple remote control that executes commands using Action.

public class RemoteControl
{
    private readonly Action _command;

    public RemoteControl(Action command)
    {
        _command = command;
    }

    public void PressButton() => _command();
}

Usage

var turnOnLight = new RemoteControl(() => Console.WriteLine("Light On"));
turnOnLight.PressButton(); // Output: Light On

var playMusic = new RemoteControl(() => Console.WriteLine("Music Playing"));
playMusic.PressButton(); // Output: Music Playing

Advantage

You can queue commands, undo, or log them — all using Action.

Combining Action and Func: Workflow Example
Let’s simulate a data processing pipeline:

Func fetchData = () => "raw data";
Func processData = data => data.ToUpper();
Action saveData = result => Console.WriteLine($"Saved: {result}");

var raw = fetchData();
var processed = processData(raw);
saveData(processed); // Output: Saved: RAW DATA

*Final Thoughts : *

Understanding and leveraging Action and Func can simplify your code, especially when implementing common patterns. They enable dynamic, reusable behaviors that are perfect for modern C# development.

Next time you’re about to create multiple strategy or command classes, consider whether delegates can do the job with less overhead.

References

Official Microsoft Docs - Delegates

C# Action Delegate

C# Func Delegate

GitHub Repo: MakeUseOfActionAndFuncDelegate