Шрифт:
Интервал:
Закладка:
и даже сократить ее до такого вида:
VerySimpleDelegate d3 = () => "Enjoy your string!";
Использование ключевого слова static с лямбда-выражениями (нововведение в версии 9.0)
Поскольку лямбда-выражения являются сокращенной формой записи для делегатов, должно быть понятно, что они тоже поддерживают ключевое слово static (начиная с версии C# 9.0) и отбрасывание (рассматривается в следующем разделе). Добавьте к операторам верхнего уровня такой код:
var outerVariable = 0;
Func<int, int, bool> DoWork = (x,y) =>
{
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, применяется синтаксис лямбда-выражений (вместо простых делегатов):
(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})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);
}
}
В качестве альтернативы теперь код может выглядеть так:
- Понимание SQL - Мартин Грубер - Базы данных