Чтение онлайн

ЖАНРЫ

Язык программирования C#9 и платформа .NET5
Шрифт:

{

outerVariable++;

return true;

};

DoWork(3,4);

Console.WriteLine("Outer variable now = {0}", outerVariable);

В результате выполнения этого кода получается следующий вывод:

***** Fun with Lambdas *****

Outer variable now = 1

Если вы сделаете лямбда-выражение статическим, тогда на этапе компиляции возникнет ошибка, т.к. выражение

пытается модифицировать переменную, объявленную во внешней области действия:

var outerVariable = 0;

Func<int, int, bool> DoWork = static (x,y) =>

{

// Ошибка на этапе компиляции по причине доступа

// к внешней переменной.

// outerVariable++;

return true;

};

Использование отбрасывания с лямбда-выражениями (нововведение в версии 9.0)

Как и в случае делегатов (начиная с версии C# 9.0), входные переменные лямбда-выражения можно заменять отбрасыванием, когда они не нужны. Здесь применяется та же самая уловка, что и в делегатах. Поскольку символ подчеркивания (

_
) в предшествующих версиях C# считался законным идентификатором переменной, в лямбда-выражении должно присутствовать два и более подчеркиваний, чтобы они трактовались как отбрасывание:

var outerVariable = 0;

Func<int, int, bool> DoWork = (x,y) =>

{

outerVariable++;

return true;

};

DoWork(_,_);

Console.WriteLine("Outer variable now = {0}", outerVariable);

Модернизация примера CarEvents с использованием лямбда-выражений

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

CarEvents
, созданный ранее в главе. Ниже приведена упрощенная версия класса
Program
из упомянутого проекта, в которой для перехвата всех событий, поступающих от объекта
Car
, применяется синтаксис лямбда-выражений (вместо простых делегатов):

using System;

using CarEventsWithLambdas;

Console.WriteLine("***** More Fun with Lambdas *****\n");

// Создать объект Car обычным образом.

Car c1 = new Car("SlugBug", 100, 10);

// Привязаться к событиям с помощью лямбда-выражений.

c1.AboutToBlow += (sender, e)

=> { Console.WriteLine(e.msg);};

c1.Exploded += (sender, e) => { Console.WriteLine(e.msg); };

// Увеличить скорость (это инициирует события).

Console.WriteLine("\n***** Speeding up *****");

for (int i = 0; i < 6; i++)

{

c1.Accelerate(20);

}

Console.ReadLine;

Лямбда-выражения

и члены, сжатые до выражений (обновление в версии 7.0)

Понимая лямбда-выражения и зная, как они работают, вам должно стать намного яснее, каким образом внутренне функционируют члены, сжатые до выражений. В главе 4 упоминалось, что в версии C# 6 появилась возможность использовать операцию

=>
для упрощения некоторых реализаций членов. В частности, если есть метод или свойство (в дополнение к специальной операции или процедуре преобразования, как было показано в главе 11), реализация которого содержит единственную строку кода, тогда определять область действия посредством фигурных скобок необязательно. Взамен можно задействовать лямбда-операцию и написать член, сжатый до выражения. В версии C# 7 такой синтаксис можно применять для конструкторов и финализаторов классов (раскрываемых в главе 9), а также для средств доступа
get
и
set
к свойствам.

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

class SimpleMath

{

public int Add(int x, int y)

{

return x + y;

}

public void PrintSum(int x, int y)

{

Console.WriteLine(x + y);

}

}

В качестве альтернативы теперь код может выглядеть так:

class SimpleMath

{

public int Add(int x, int y) => x + y;

public void PrintSum(int x, int y) => Console.WriteLine(x + y);

}

В идеале к этому моменту вы должны уловить суть лямбда-выражений и понимать, что они предлагают "функциональный способ" работы с анонимными методами и типами делегатов. Хотя на привыкание к лямбда-операции (

=>
) может уйти некоторое время, просто запомните, что лямбда-выражение сводится к следующей форме:

АргументыДляОбработки =>

{

ОбрабатывающиеОператоры

}

Или, если операция

=>
используется для реализации члена типа с единственным оператором, то это будет выглядеть так:

ЧленТипа => ЕдинственныйОператорКода

Полезно отметить, что лямбда-выражения широко задействованы также в модели программирования LINQ, помогая упростить кодирование. Исследование LINQ начинается в главе 13.

Поделиться с друзьями: