*
Previous Asynchronous Programming with async/await in C# Memory Management in C# Next

💡 Functional Programming in C#

🧠 Functional Programming in C#

Functional programming is a paradigm that emphasizes the evaluation of mathematical functions, avoids mutable state and side effects, and treats functions as first-class citizens. In C#, a traditionally object-oriented language, functional programming concepts are supported through features like lambda expressions, Func, and Action. These are widely used in modern C#, particularly in Language Integrated Query (LINQ).

⚙️ Lambda Expressions

A lambda expression is a concise way to define an anonymous function (a function without a name). They use the => operator.

  • Expression Lambda: Used for a single expression.
  • Statement Lambda: Used for a block of statements enclosed in braces {}.

Syntax: (input-parameters) => expression-or-statement-block

🔹 Example

// Expression lambda for a simple calculation
Func<int, int> square = x => x * x;
Console.WriteLine(square(5)); // Output: 25

// Statement lambda with multiple lines
Action<string> greet = name =>
{
    string greeting = $"Hello, {name}!";
    Console.WriteLine(greeting);
};
greet("Functional C#"); // Output: Hello, Functional C#!

Use code with caution.

🧩 Func Delegates

Func is a predefined generic delegate type that represents a method that takes one or more input parameters and returns a value. The last type parameter in the Func declaration is always the return type. It supports up to 16 input parameters.

Syntax: Func<T1, T2, ..., TResult>

🔹 Example: Func with a Lambda Expression

// Takes two integers and returns their sum
Func<int, int, int> add = (a, b) => a + b;
int sum = add(10, 20);
Console.WriteLine($"The sum is: {sum}"); // Output: The sum is: 30

// Takes a string and returns a boolean (used with LINQ's Where method)
Func<string, bool> hasLengthThree = str => str.Length == 3;
string[] words = { "cat", "dog", "elephant", "bird" };
var result = words.Where(hasLengthThree);
// result will contain "cat" and "dog"

Use code with caution.

⚡ Action Delegates

Action is a predefined generic delegate type that represents a method that takes one or more input parameters but returns no value (void). Like Func, it supports up to 16 input parameters.

Syntax: Action<T1, T2, ...>

🔹 Example: Action with a Lambda Expression

// Takes a string and prints it to the console
Action<string> printMessage = message => Console.WriteLine(message);
printMessage("This is an action delegate."); // Output: This is an action delegate.

// Takes two integers and performs an action
Action<int, int> displaySum = (x, y) => Console.WriteLine($"The sum is {x + y}.");
displaySum(5, 8); // Output: The sum is 13.

Use code with caution.

🔍 How They Enable Functional Programming in C#

  • Higher-Order Functions: Functions can be passed as arguments or returned from other functions. Func and Action delegates enable this, making code highly reusable. LINQ methods like Where, Select, and OrderBy are examples of higher-order functions.
  • Immutability: Functional programming promotes immutability to minimize side effects and improve predictability. Although C# isn’t strictly immutable, lambda expressions and LINQ transformations produce new collections rather than modifying existing ones.
  • Declarative Style: Instead of writing imperative loops like foreach, developers can express intent using declarative LINQ expressions combined with lambdas—focusing on what to do, not how to do it.

C# supports functional programming concepts through delegates, lambda expressions, and built-in types like Func and Action. These features allow you to treat functions as first-class citizens—passing them as parameters, returning them, and composing them.

🔹 Lambda Expressions

A lambda expression is an anonymous function that can contain expressions or statements. It uses the => syntax.

Func square = x => x * x;
Console.WriteLine(square(5)); // Output: 25

🔹 Func Delegate

Func<T, TResult> represents a method that takes parameters and returns a value.

Func add = (a, b) => $"{a} + {b} = {a + b}";
Console.WriteLine(add(3, 4)); // Output: 3 + 4 = 7

🔹 Action Delegate

Action<T> represents a method that takes parameters but returns void.

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

🔹 Predicate Delegate

Predicate<T> is a special Func<T, bool> used for filtering.

Predicate isEven = x => x % 2 == 0;
Console.WriteLine(isEven(4)); // Output: True

✅ Best Practices

  • Use lambdas for short, inline logic.
  • Use Func for methods that return values.
  • Use Action for methods that perform actions without returning values.
  • Use Predicate for filtering logic.
  • Keep lambdas concise and readable.

📌 When to Use

  • In LINQ queries for filtering, projection, and transformation.
  • To pass behavior as parameters (e.g., callbacks).
  • For event handling and asynchronous programming.
  • To simplify code and reduce boilerplate.

🚫 When Not to Use

  • For complex logic—use named methods instead.
  • When readability suffers due to nested lambdas.
  • In performance-critical paths—delegates may add overhead.

⚠️ Precautions

  • Avoid capturing variables in lambdas that may change unexpectedly.
  • Be cautious with closures and memory leaks.
  • Use meaningful parameter names for clarity.

🎯 Advantages

  • Concise: Reduces boilerplate code.
  • Flexible: Enables higher-order functions.
  • Reusable: Functions can be passed and composed.
  • Declarative: Improves readability and expressiveness.

📝 Conclusion

Functional programming in C# empowers developers to write clean, expressive, and reusable code. By mastering lambdas, Func, and Action, you unlock powerful patterns for building modern and maintainable applications.

🏁 Summary

Functional programming in C# enhances code readability, reusability, and maintainability. Through lambda expressions, Func, and Action delegates, developers can adopt a declarative and expressive style while still leveraging the full power of C#’s object-oriented capabilities.

Back to Index
Previous Asynchronous Programming with async/await in C# Memory Management in C# Next
*
*