Рейтинговые книги
Читем онлайн Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 160 161 162 163 164 165 166 167 168 ... 407
class="p1">    // текущее значение i

    Console.WriteLine("value of i is currently: {0}", i);

    bool isEven = ((i % 2) == 0);

    return isEven;

  });

  // Вывести четные числа

  Console.WriteLine("Here are your even numbers:");

  foreach (int evenNumber in evenNumbers)

  {

    Console.Write("{0}t", evenNumber);

  }

  Console.WriteLine();

}

В данном случае список параметров (опять состоящий из единственного целочисленного значения i) обрабатывается набором операторов кода. Помимо вызова метода Console.WriteLine() оператор вычисления остатка от деления разбит на два оператора ради повышения читабельности. Предположим, что каждый из рассмотренных выше методов вызывается внутри операторов верхнего уровня:

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

TraditionalDelegateSyntax();

AnonymousMethodSyntax();

Console.WriteLine();

LambdaExpressionSyntax();

Console.ReadLine();

Запуск приложения дает следующий вывод:

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

Here are your even numbers:

20      4       8       44

Here are your even numbers:

20      4       8       44

value of i is currently: 20

value of i is currently: 1

value of i is currently: 4

value of i is currently: 8

value of i is currently: 9

value of i is currently: 44

Here are your even numbers:

20      4       8       44 

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

Показанные ранее лямбда-выражения обрабатывали единственный параметр. Тем не менее, это вовсе не обязательно, т.к. лямбда-выражения могут обрабатывать множество аргументов (или ни одного). Для демонстрации первого сценария с множеством аргументов добавьте показанную ниже версию класса SimpleMath:

public class SimpleMath

{

  public delegate void MathMessage(string msg, int result);

  private MathMessage _mmDelegate;

  public void SetMathHandler(MathMessage target)

  {

    _mmDelegate = target;

  }

  public void Add(int x, int y)

  {

    _mmDelegate?.Invoke("Adding has completed!", x + y);

  }

}

Обратите внимание, что делегат MathMessage ожидает два параметра. Чтобы представить их в виде лямбда-выражения, операторы верхнего уровня можно записать так:

// Зарегистрировать делегат как лямбда-выражение.

SimpleMath m = new SimpleMath();

m.SetMathHandler((msg, result) =>

  {Console.WriteLine("Message: {0}, Result: {1}", msg, result);});

// Это приведет к выполнению лямбда-выражения.

m.Add(10, 10);

Console.ReadLine();

Здесь задействовано выведение типа, поскольку для простоты два параметра не были строго типизированы. Однако метод SetMathHandler() можно было бы вызвать следующим образом:

m.SetMathHandler((string msg, int result) =>

  {Console.WriteLine("Message: {0}, Result: {1}", msg, result);});

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

public delegate string VerySimpleDelegate();

вот как можно было бы обработать результат вызова:

// Выводит на консоль строку "Enjoy your string!".

VerySimpleDelegate d =

  new VerySimpleDelegate( () => {return "Enjoy your string!";} );

Console.WriteLine(d());

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

VerySimpleDelegate d2 =

  new VerySimpleDelegate(() => "Enjoy your string!");

и даже сократить ее до такого вида:

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, применяется синтаксис лямбда-выражений (вместо простых делегатов):

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)

Понимая лямбда-выражения и зная, как

1 ... 160 161 162 163 164 165 166 167 168 ... 407
На этой странице вы можете бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен бесплатно.

Оставить комментарий