C# Lambda Expressions

Writing concise anonymous functions in C#

⚡ What are Lambda Expressions?

Lambda expressions are anonymous functions that provide a concise way to write inline code blocks. They use the => operator to separate parameters from the function body, making code cleaner and more readable.


// Simple lambda expression
Func<int, int> square = x => x * x;
Console.WriteLine(square(5)); // Output: 25
                                    

Output:

25

Key Lambda Concepts

📝

Basic Syntax

Simple parameter to expression

x => x * 2
🔢

Multiple Parameters

Use parentheses for multiple inputs

(x, y) => x + y
📦

Statement Body

Use braces for multiple statements

x => { 
  var result = x * 2;
  return result;
}
🎯

No Parameters

Empty parentheses for no input

() => Console.WriteLine("Hi")

🔹 Basic Lambda Expression

Lambda expressions provide a concise syntax for writing anonymous methods using the => operator. They consist of input parameters and an expression or statement block. For example, x => x * x squares a number, returning 16 for input 4 and 49 for 7. Lambdas are ideal for short, inline operations like mathematical computations or simple transformations, reducing the need for formally declared methods and keeping code compact and functional in style.

// Traditional method
int Square(int x) 
{
    return x * x;
}

// Lambda expression equivalent
Func<int, int> square = x => x * x;

// Using the lambda
Console.WriteLine(square(4));  // Output: 16
Console.WriteLine(square(7));  // Output: 49

Output:

16

49

🔹 Lambda with Multiple Parameters

Lambda expressions can accept multiple parameters by enclosing them in parentheses, enabling more complex operations. For arithmetic, (a, b) => a + b adds two numbers (e.g., 3 + 5 = 8). For multiplication, (x, y) => x * y computes products (6 * 4 = 24). They also support logical operations like finding the maximum: (p, q) => p > q ? p : q returns 6 from 6 and 4. This syntax remains clean and expressive, perfect for mathematical, comparison, or combining logic directly within method calls.

// Lambda with two parameters
Func<int, int, int> add = (x, y) => x + y;
Func<int, int, int> multiply = (x, y) => x * y;

Console.WriteLine(add(5, 3));       // Output: 8
Console.WriteLine(multiply(4, 6));  // Output: 24

// Lambda with three parameters
Func<int, int, int, int> sum = (a, b, c) => a + b + c;
Console.WriteLine(sum(1, 2, 3));    // Output: 6

Output:

8

24

6

🔹 Lambda with Statement Body

For more complex logic, lambda expressions can use a statement body with curly braces and explicit return. This allows multiple statements, variable declarations, and conditionals. For example, a lambda that checks a number's sign: x => { if (x > 0) return "Positive"; else if (x < 0) return "Negative"; else return "Zero"; }. It returns "Positive" for positive inputs, "Negative" for negative, and "Zero" for zero. This maintains inline convenience while accommodating moderate complexity without separate method definitions.

// Lambda with multiple statements
Func<int, string> checkNumber = x => 
{
    if (x > 0)
        return "Positive";
    else if (x < 0)
        return "Negative";
    else
        return "Zero";
};

Console.WriteLine(checkNumber(10));   // Output: Positive
Console.WriteLine(checkNumber(-5));   // Output: Negative
Console.WriteLine(checkNumber(0));    // Output: Zero

Output:

Positive

Negative

Zero

🔹 Lambda with LINQ

Lambda expressions are integral to LINQ (Language Integrated Query) for functional-style data manipulation on collections. Methods like Where, Select, and OrderBy accept lambdas to filter, project, and sort data concisely. For instance, numbers.Where(n => n % 2 == 0) filters even numbers (2, 4, 6, 8, 10). Select(n => n * n) squares them (1, 4, 9, 16, 25). Chaining operations like .Where(...).Select(...) yields results like 12, 14, 16, 18, 20. This enables readable, efficient data queries without verbose loops.

using System;
using System.Linq;
using System.Collections.Generic;

List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

// Filter even numbers
var evenNumbers = numbers.Where(x => x % 2 == 0);
Console.WriteLine("Even: " + string.Join(", ", evenNumbers));

// Square each number
var squared = numbers.Select(x => x * x);
Console.WriteLine("Squared: " + string.Join(", ", squared.Take(5)));

// Filter and transform
var result = numbers.Where(x => x > 5).Select(x => x * 2);
Console.WriteLine("Filtered & Doubled: " + string.Join(", ", result));

Output:

Even: 2, 4, 6, 8, 10

Squared: 1, 4, 9, 16, 25

Filtered & Doubled: 12, 14, 16, 18, 20

🔹 Action and Func Delegates

The Action and Func built-in delegate types work seamlessly with lambda expressions for different purposes. Action represents a void method, used for side effects like printing: Action<string> greet = name => Console.WriteLine($"Hello, {name}!"); outputs "Hello, Alice!". Func represents a method returning a value, used for computations: Func<int, int, int> add = (a, b) => a + b; returns 20 for 10+10. They encapsulate behavior inline, promoting functional programming patterns in C#.

// Action - no return value
Action<string> greet = name => Console.WriteLine($"Hello, {name}!");
greet("Alice");  // Output: Hello, Alice!

// Func - returns a value
Func<int, int, int> max = (a, b) => a > b ? a : b;
Console.WriteLine(max(10, 20));  // Output: 20

// Action with multiple parameters
Action<string, int> display = (name, age) => 
    Console.WriteLine($"{name} is {age} years old");
display("Bob", 25);  // Output: Bob is 25 years old

Output:

Hello, Alice!

20

Bob is 25 years old

🧠 Test Your Knowledge

What operator is used in lambda expressions?