Lambda expressions. General concepts of lambda expressions. Lambda operator. Single and block lambda expressions

 Lambda expressions. General concepts of lambda expressions. Lambda operator. Single and block lambda expressions

 


Content


1. What are the ways to create anonymous functions?

In C# there are two ways to create anonymous functions:

  • anonymous methods;
  • lambda expressions.

In more detail the work of anonymous methods described in the topics:

 

2. Why use lambda expressions in C#?

The purpose of using lambda expressions is exactly the same as anonymous methods. Lambda expressions are an alternative to anonymous methods. Lambda expressions allow you to program functions in a simplified form without using a name with the help of a special operator, which is denoted by ‘=>’.

 

3. What is a lambda operator?

The lambda operator is denoted by ‘=>’. Literally, you can form a lambda operator as “passes” or “becomes”. The “=>” operator divides the lambda expression into two parts.

One input parameter or several input parameters are specified on the left side of the lambda operator. The lambda expression is specified on the right side of the lambda operator.

 

4. What are the types of lambda expressions?

In C#, there are two types of lambda expressions:

  • single lambda expressions;
  • the block lambda expressions.

 

5. What is the general form of declaring a single lambda expression? Examples

The general form of declaring a single lambda expression that takes one parameter:

parameter => expression

where

  • parameter – a parameter that receives a lambda expression at the input;
  • expression – directly the expression that is evaluated.

The general form of declaring a single lambda expression that takes multiple parameters:

(parameters_list) => expression

where

  • parameters_list – two or more parameters that are used in the lambda expression.

Example 1 of a single lambda expression that calculates the value of cos(x+2):

x => Math.Cos(x + 2);

In this example, x is an input parameter. This expression replaces the function of the following form:

double CalcCos2(double x)
{
    return Math.Cos(x + 2);
}

As can be seen from the program code, the use of lambda expression simplifies the program code, especially in cases when it is necessary to call methods that perform different work but have the same signature.

Example 2 of a single lambda expression that receives 3 parameters with the names a, b, c. In this example, is it possible to form a triangle from the lengths of the sides a, b, c?

(a, b, c) => ((a + b) > c) && ((a + c) > b) && ((b + c) > a);

In the above lambda expression, the rule is used: the sum of any two lengths of the sides of the triangle is greater than the length of the third side.

 

6. What is the general form of declaring a block lambda expression? Example

The general form of declaring a block lambda expression that receives one parameter:

parameter =>
{
    // instructions, expressions
    // ...
}

The general form of declaring a block lambda expression that receives several parameters:

(parameters_list) =>
{
    // instructions, expressions
    // ...
}

Example.

In the example, a lambda expression is declared that receives an integer value of x. In the lambda expression code, the number of digits ‘5’ in the integer x is counted. For example, for a number of 5854, the lambda expression returns the value 2.

x =>
{
    int t, d, k;
    t = Math.Abs(x);
    k = 0; // the number of digits '5'
    while (t > 0)
    {
        d = t % 10;
        if (d == 5) k++;
        t = t / 10;
    }
    return k;
};

Returning the value is carried out by the return statement.

 

7. What actions (steps) need to be taken to apply a lambda expression in the program? Example

In order to apply a lambda expression in the code, you need to do the following:

  1. Declare the type of delegate that is shared with the lambda expression.
  2. Declare a variable of this type of delegate (delegate instance).
  3. Assign a lambda expression to the variable (delegate instance).
  4. Call the variable (delegate instance) in the program code.

Example. We will go through all the steps sequentially for the task from the preceding paragraph (clause 6). Suppose it is needed to demonstrate the operation of a lambda expression, which receives an input parameter an integer x and computes the number of digits ‘5’ in this number.

  1. Declare the delegate type. The delegate type is declared in a certain class.
// Declare the delegate type
delegate int CalcNum5(int x);

Name of the delegate type CalcNum5. A delegate of this type will receive one input parameter (x). A delegate of this type returns an int value.

  1. Declare a variable of this type of delegate. A variable is declared in some code. This can be an arbitrary code of class method, an event handler code, and so on.
CalcNum5 CN;
  1. Assign a lambda expression to the variable.In the method of declaring a variable is declared assignment:
CN = x =>
{
    int t, d, k;
    t = Math.Abs(x);
    k = 0; // the count of digits '5'
    while (t > 0)
    {
        d = t % 10;
        if (d == 5) k++;
        t = t / 10;
    }
    return k;
};

A variable can be initialized with a lambda expression as soon as it is declared (step 2), in accordance with the C# syntax. In abbreviated form, it looks like this:

CalcNum5 CN = x =>
{
    ...
};

 

  1. Call the variable. In the same method where the lambda expression is declared, a variable call is implemented. The name CN is the name of the delegate that contains the lambda expression.
// the use of lambda expression
int a = 615;
int res;
res = CN(a); // res = 1

 

8. An example of using a single lambda expression that receives one parameter

In this example, is demonstrated the use of a lambda expression, in which the function y = sin2x is calculated.

First, the type of the delegate is declared, which receives one parameter of type float and returns a value of type float. The parameter has the name – x. The event handler button1_Click() demonstrates the use of a lambda expression.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TrainLyambda
{
    public partial class Form1 : Form
    {
        // Declare the type of the delegate that receives 1 parameter and returns the value
        delegate float GetSin2X(float x);

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // A lambda expression that receives 1 parameter and returns a value
            GetSin2X y = x => (float)(Math.Sin(x) * Math.Sin(x));

            // Demonstration of the use of lambda expression
            float z;
            const float Pi = 3.1415f;
            z = y(0.0f); // z = 0
            z = y((float)(Pi / 2.0)); // z = 1
            z = y(0.7f); // z = 0.4150164

            label1.Text = z.ToString();
       }
    }
}

 

9. An example of using a single lambda expression that receives several parameters

In this example, for the given x, y, the function z=sin x2 – 2·cos y is computed. To declare a lambda expression, you first need to declare a delegate type that receives 2 parameters and returns a value. Type of parameters and values is double.

The declaration of the delegate type is:

// Declare the type of delegate that receives 2 parameters and returns a value
delegate double CalcZ(double x, double y);

Demonstration of using a lambda expression from another method (for example, an event handler)

// Demonstration of using a lambda expression
// Declare a variable of type "delegate"
CalcZ Z;

// declare a lambda expression that receives 2 parameters with the names x, y
Z = (x, y) => Math.Sin(x * x) - 2 * Math.Cos(y);

// use a lambda expression to calculate
double t;
t = Z(0.0, 0.0); // t = -2
t = Z(3.3, 1.8); // t = -0.540028

 

10. An example of a block lambda expression that receives several parameters
Task

Three different integers are given. Implement a lambda expression that finds the largest of these three numbers.

Decision

First, declares the type of the delegate that receives three integer type parameters and returns an integer value

// type of delegate that receives 3 integer parameters and returns an integer value
delegate int CalcMax(int a, int b, int c);

Then, in another program code, you can declare a lambda expression and demonstrate its work

// declare a delegate
CalcMax CM;

// implement a lambda expression that receives 3 parameters x, y, z
// and returns the maximum value from these parameters
CM = (x, y, z) =>
{
    int max = x;
    if (max < y) max = y;
    if (max < z) max = z;
    return max;
};

// use a lambda expression to find the maximum
int a = 8, b = 5, c = 10;
int Max;
Max = CM(a, b, c); // Max = 10
Max = CM(a + 8, b - 3, c + 1); // Max = 16

 

11. Is it possible to implement different lambda expressions in one method, which correspond to the same type of delegate?

Yes, it is.

Example.

Let the delegate type be declared, which receives three integer type parameters.

// delegate type declaration
delegate int CalcABC(int a, int b, int c);

Then, in the event handler or in another method, you can write this:

// Declare the delegate
CalcMax CM;

// 1. Implement a lambda expression that receives 3 parameters x, y, z
// and returns the maximum value from these parameters
CM = (x, y, z) =>
{
    int max = x;
    if (max < y) max = y;
    if (max < z) max = z;
    return max;
};

// use a lambda expression to find the maximum
int a = 8, b = 5, c = 10;
int Max;
Max = CM(a, b, c); // Max = 10
Max = CM(a + 8, b - 3, c + 1); // Max = 16
label1.Text = "Maximum = " + Max.ToString();

// 2. A lambda expression that calculates the sum of 3 numbers
CM = (x, y, z) =>
{
    int s;
    s = z + x + y;
    return s;
};

int sum = CM(4, 3, 2); // sum = 9

label1.Text = "Sum of numbers = " + sum.ToString();

// 3. A lambda expression that calculates a product of 3 numbers
CM = (t, u, v) =>
{
    int mult = t * u * v;
    return mult;
};

int Mult = CM(5, 3, 10); // Mult = 150
label1.Text = "Multiplication = " + Mult.ToString();

In the above code for one type of CalcABC delegate, 3 lambda expressions are implemented that perform the following operations on input parameters:

  • find the maximum value;
  • find the sum of the parameters;
  • find the multiplication of the parameters.

This example shows the benefits of using delegates in C# programs. The delegate has one signature (declared in the type), but depending on the situation, when the delegate is called, different work is performed (program code).

This approach is effective when writing large software systems, where different code fragments (objects) give signals to one delegate that it needs to do some work. What kind of work the delegate can perform is determined depending on the situation and the object that generated the message. As a result, so-called events are generated, which are processed using delegates. Considering the work of events is another (next) topic.

 


Related topics