СДЕЛАЙТЕ СВОИ УРОКИ ЕЩЁ ЭФФЕКТИВНЕЕ, А ЖИЗНЬ СВОБОДНЕЕ

Благодаря готовым учебным материалам для работы в классе и дистанционно

Скидки до 50 % на комплекты
только до

Готовые ключевые этапы урока всегда будут у вас под рукой

Организационный момент

Проверка знаний

Объяснение материала

Закрепление изученного

Итоги урока

Лямбды языка C#

Категория: Информатика

Нажмите, чтобы узнать подробности

Просмотр содержимого документа
«Лямбды языка C#»

Лямбда-выражения представляют упрощенную запись анонимных методов. Лямбда-выражения позволяют создать емкие лаконичные методы, которые могут возвращать некоторое значение и которые можно передать в качестве параметров в другие методы.

Ламбда-выражения имеют следующий синтаксис: слева от лямбда-оператора = определяется список параметров, а справа блок выражений, использующий эти параметры: (список_параметров) = выражение. Например:

1

2

3

4

5

6

7

8

9

10

11

class Program

{

    delegate int Operation(int x, int y);

    static void Main(string[] args)

    {

        Operation operation = (x, y) = x + y;

        Console.WriteLine(operation(10, 20));       // 30

        Console.WriteLine(operation(40, 20));       // 60

        Console.Read();

    }

}

Здесь код (x, y) = x + y; представляет лямбда-выражение, где x и y - это параметры, а x + y - выражение. При этом нам не надо указывать тип параметров, а при возвращении результата не надо использовать оператор return.

При этом надо учитывать, что каждый параметр в лямбда-выражении неявно преобразуется в соответствующий параметр делегата, поэтому типы параметров должны быть одинаковыми. Кроме того, количество параметров должно быть таким же, как и у делегата. И возвращаемое значение лямбда-выражений должно быть тем же, что и у делегата. То есть в данном случае использованное лямбда-выражение соответствует делегату Operation как по типу возвращаемого значения, так и по типу и количеству параметров.

Если лямбда-выражение принимает один параметр, то скобки вокруг параметра можно опустить:

1

2

3

4

5

6

7

8

9

10

11

12

class Program

{

    delegate int Square(int x); // объявляем делегат, принимающий int и возвращающий int

    static void Main(string[] args)

    {

        Square square = i = i * i; // объекту делегата присваивается лямбда-выражение

 

        int z = square(6); // используем делегат

        Console.WriteLine(z); // выводит число 36

        Console.Read();

    }

}

Бывает, что параметров не требуется. В этом случае вместо параметра в лямбда-выражении используются пустые скобки. Также бывает, что лямбда-выражение не возвращает никакого значения:

1

2

3

4

5

6

7

8

9

10

11

12

class Program

{

    delegate void Hello(); // делегат без параметров

    static void Main(string[] args)

    {

        Hello hello1 = () = Console.WriteLine("Hello");

        Hello hello2 = () = Console.WriteLine("Welcome");

        hello1();       // Hello

        hello2();       // Welcome

        Console.Read();

    }

}

В данном случае лямда-выражение ничего не возвращает, так как после лямбда-оператора идет действие, которое ничего не возвращает.

Как видно, из примеров выше, нам необязательно указывать тип параметров у лямбда-выражения. Однако, нам обязательно нужно указывать тип, если делегат, которому должно соответствовать лямбда-выражение, имеет параметры с модификаторами ref и out:

1

2

3

4

5

6

7

8

9

10

11

12

class Program

{

    delegate void ChangeHandler(ref int x);

    static void Main(string[] args)

    {

        int x = 9;

        ChangeHandler ch = (ref int n) = n = n * 2;

        ch(ref x);

        Console.WriteLine(x);   // 18

        Console.Read();

    }

}

Лямбда-выражения также могут выполнять другие методы:

1

2

3

4

5

6

7

8

9

10

11

12

13

class Program

{

    delegate void Hello(); // делегат без параметров

    static void Main(string[] args)

    {

        Hello message = () = Show_Message();

        message();

    }

    private static void Show_Message()

    {

        Console.WriteLine("Привет мир!");

    }

}

Лямбда-выражения как аргументы методов

Как и делегаты, лямбда-выражения можно передавать в качестве аргументов методу для тех параметров, которые представляют делегат, что довольно удобно:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

class Program 

{

    delegate bool IsEqual(int x);

     

    static void Main(string[] args)

    {

        int[] integers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

         

        // найдем сумму чисел больше 5

        int result1 = Sum(integers, x = x 5);

        Console.WriteLine(result1); // 30

         

        // найдем сумму четных чисел

        int result2 = Sum(integers, x = x % 2 == 0);

        Console.WriteLine(result2);  //20

         

        Console.Read();

    }

 

    private static int Sum (int[] numbers, IsEqual func)

    {

        int result = 0;

        foreach(int i in numbers)

        {

            if (func(i))

                result += i;

        }

        return result;

    }

}

Метод Sum принимает в качестве параметра массив чисел и делегат IsEqual и возвращает сумму чисел массива в виде объекта int. В цикле проходим по всем числам и складываем их. Причем складываем только те числа, для которых делегат IsEqual func возвращает true. То есть делегат IsEqual здесь фактически задает условие, которому должны соответствовать значения массива. Но на момент написания метода Sum нам неизвестно, что это за условие.

При вызове метода Sum ему передается массив и лямбда-выражение:

1

int result1 = Sum(integers, x = x 5);

То есть параметр x здесь будет представлять число, которое передается в делегат:

1

if (func(i))

А выражение x 5 представляет условие, которому должно соответствовать число. Если число соответствует этому условию, то лямбда-выражение возвращает true, а переданное число складывается с другими числами.

Подобным образом работает второй вызов метода Sum, только здесь уже идет проверка числа на четность, то есть если остаток от деления на 2 равен нулю:

1

int result2 = Sum(integers, x = x % 2 == 0);