C# lambda expression

By FoxLearn 12/15/2024 4:27:53 AM   191
A lambda expression is a concise, anonymous function not tied to an identifier, allowing for more streamlined and readable code.

For example, Filtering a list with a lambda expression

static void Main()
{
    // Define an array of integers
    int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    // Use LINQ with a lambda expression to filter even numbers
    var evenNumbers = numbers.Where(n => n % 2 == 0);

    // Use LINQ with a lambda expression to find numbers greater than 5
    var greaterThanFive = numbers.Where(n => n > 5);

    // Use LINQ with a lambda expression to calculate the square of each number
    var squares = numbers.Select(n => n * n);

    // Print the results
    Console.WriteLine("Even Numbers: " + string.Join(", ", evenNumbers));
    Console.WriteLine("Numbers Greater Than Five: " + string.Join(", ", greaterThanFive));
    Console.WriteLine("Squares: " + string.Join(", ", squares));
}

Output:

Even Numbers: 2, 4, 6, 8, 10
Numbers Greater Than Five: 6, 7, 8, 9, 10
Squares: 1, 4, 9, 16, 25, 36, 49, 64, 81, 100

The example demonstrates using lambda expressions with LINQ's Select and Where methods for data filtering and transformation. The lambda expression is used as an argument to the Where method to filter out even numbers.

Func<int, int> square = x => x * x;
Func<int, int, int> add = (x, y) => x + y;

Console.WriteLine(square(6));
Console.WriteLine(add(4, 5));

Output:

36
9

A Func delegate in C# represents a lambda expression that performs operations, such as squaring an input value, making it similar to plain functions in other languages.

C# lambda statement

A lambda expression can include multiple statements, enclosed within {} braces.

static void Main()
{
    // Define an Action delegate with a lambda statement
    Action<int> printSquareAndCube = (number) =>
    {
        int square = number * number;
        int cube = number * number * number;
        Console.WriteLine($"Number: {number}, Square: {square}, Cube: {cube}");
    };

    // Call the lambda statement
    printSquareAndCube(3);
}

Output:

Number: 3, Square: 9, Cube: 27
  • (number) => { ... } is a lambda statement.
  • The {} braces allow multiple statements inside the lambda body.

The Action<int> delegate represents a method that takes an int as input and returns no value.

C# lambda expression with arrays

static void Main()
{
    // Define an array of integers
    int[] values = { 5, -1, 3, 7, 0, -5, 4, 3, 2 };

    // Find the index of the first occurrence of the value 3
    var firstIndex = Array.FindIndex(values, x => x == 3);
    Console.WriteLine($"First index of 3: {firstIndex}");

    // Find the index of the last occurrence of the value 3
    var lastIndex = Array.FindLastIndex(values, x => x == 3);
    Console.WriteLine($"Last index of 3: {lastIndex}");

    // Find all positive values in the array
    var positives = Array.FindAll(values, x => x > 0);
    Console.WriteLine($"Positive values: {string.Join(", ", positives)}");

    // Find the first negative number in the array
    var firstNegative = Array.Find(values, x => x < 0);
    Console.WriteLine($"First negative value: {firstNegative}");

    // Count how many values are even
    var evenCount = Array.FindAll(values, x => x % 2 == 0).Length;
    Console.WriteLine($"Count of even numbers: {evenCount}");
}

Output:

First index of 3: 2
Last index of 3: 7
Positive values: 5, 3, 7, 4, 3, 2
First negative value: -1
Count of even numbers: 3

The Array.FindIndex and Array.FindLastIndex methods return the index of the first or last occurrence of a value that satisfies the given predicate.

For example: x => x == 3 checks if the value is equal to 3.

The Array.FindAll method returns an array of all elements that satisfy the given condition.

For example: x => x > 0 checks if the value is positive.

The Array.Find method returns the first element in the array that matches the predicate.

For example: x => x < 0 checks if the value is negative.

C# array of lambda expressions

The example shows how to create an array of lambda expressions.

static void Main()
{
    // Define an array of lambda expressions of type Func<int, int>
    Func<int, int>[] operations =
    {
                x => x * x,  // Squaring the number
                x => x + 2,  // Adding 2 to the number
                x => x - 1   // Subtracting 1 from the number
            };

    // Iterate through numbers 0 to 5 and apply each lambda expression
    for (int i = 0; i < 6; i++)
    {
        Console.WriteLine($"Input: {i}");
        Console.WriteLine($"Square: {operations[0](i)}");
        Console.WriteLine($"Add 2: {operations[1](i)}");
        Console.WriteLine($"Subtract 1: {operations[2](i)}");
        Console.WriteLine();
    }
}

Output:

Input: 0
Square: 0
Add 2: 2
Subtract 1: -1

Input: 1
Square: 1
Add 2: 3
Subtract 1: 0

Input: 2
Square: 4
Add 2: 4
Subtract 1: 1

Input: 3
Square: 9
Add 2: 5
Subtract 1: 2

Input: 4
Square: 16
Add 2: 6
Subtract 1: 3

Input: 5
Square: 25
Add 2: 7
Subtract 1: 4

C# lambda expression discards

Since C# 9.0, we can use discards (_) as parameters in lambda expressions and anonymous methods to indicate that the parameter is not used.

static void Main()
{
    // An array of numbers
    int[] numbers = { 1, 2, 3, 4, 5 };

    // Lambda expression with discard (_) to ignore the parameter
    // We're only interested in the second element of the array
    var secondElement = Array.Find(numbers, (_, index) => index == 1);

    Console.WriteLine($"Second element: {secondElement}");

    // Lambda expression using discard for a method that doesn't need a parameter
    // Here, we simply perform an action without using the parameter
    Action<int> printMessage = _ => Console.WriteLine("This lambda ignores its input.");
    printMessage(10); // The parameter is ignored
}

Output:

Second element: 2
This lambda ignores its input.

In the Array.Find method, we use (_, index) to discard the first parameter (_) and only use the second parameter (index). This way, we can ignore the value itself and just work with the index.

The printMessage action uses a discard (_) to indicate the input parameter is not used within the lambda expression, making it clearer that the parameter is intentionally ignored.