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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 243 244 245 246 247 248 249 250 251 ... 642

c1.AboutToBlow += delegate(object sender, CarEventArgs e)

{

  Console.WriteLine("Critical Message from Car: {0}", e.msg);

};

Доступ к локальным переменным

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

• Анонимный метод не имеет доступа к параметрам ref и out определяющего метода.

• Анонимный метод не может иметь локальную переменную, имя которой совпадает с именем локальной переменной внешнего метода.

• Анонимный метод может обращаться к переменным экземпляра (или статическим переменным) из области действия внешнего класса.

• Анонимный метод может объявлять локальную переменную с тем же именем, что и у переменной-члена внешнего класса (локальные переменные имеют отдельную область действия и скрывают переменные-члены из внешнего класса).

Предположим, что в операторах верхнего уровня определена локальная переменная по имени aboutToBlowCounter типа int. Внутри анонимных методов, которые обрабатывают событие AboutToBlow, выполните увеличение значения aboutToBlowCounter на 1 и вывод результата на консоль перед завершением операторов:

Console.WriteLine("***** Anonymous Methods *****n");

int aboutToBlowCounter = 0;

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

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

// Зарегистрировать обработчики событий как анонимные методы.

c1.AboutToBlow += delegate

{

<b>  aboutToBlowCounter++;</b>

  Console.WriteLine(&quot;Eek! Going too fast!&quot;);

};

c1.AboutToBlow += delegate(object sender, CarEventArgs e)

{

<b>  aboutToBlowCounter++;</b>

  Console.WriteLine(&quot;Critical Message from Car: {0}&quot;, e.msg);

};

...

// В конце концов, это будет инициировать события.

for (int i = 0; i &lt; 6; i++)

{

  c1.Accelerate(20);

}

Console.WriteLine(&quot;AboutToBlow event was fired {0} times.&quot;,

  aboutToBlowCounter);

Console.ReadLine();

(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})

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

Использование ключевого слова static с анонимными методами (нововведение в версии 9.0)

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

static int AddWrapperWithStatic(int x, int y)

{

  // Выполнить проверку достоверности

  return Add(x,y);

  static int Add(int x, int y)

  {

    return x + y;

  }

}

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

c1.AboutToBlow += static delegate

{

  // Этот код приводит к ошибке на этапе компиляции,

  // потому что анонимный метод помечен как статический

  aboutToBlowCounter++;

  Console.WriteLine(&quot;Eek! Going too fast!&quot;);

};

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

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

Отбрасывание, представленное в главе 3, в версии C# 9.0 было обновлено с целью применения в качестве входных параметров, но с одной уловкой. Поскольку символ подчеркивания (_) в предшествующих версиях C# считался законным идентификатором переменной, в анонимном методе должно присутствовать два и более подчеркиваний, чтобы они трактовались как отбрасывание.

Например, в следующем коде создается делегат Func&lt;&gt;, который принимает два целых числа и возвращает еще одно целое число. Приведенная реализация игнорирует любые переданные переменные и возвращает значение 42:

Console.WriteLine(&quot;******** Discards with Anonymous Methods ********&quot;);

Func&lt;int,int,int&gt; constant = delegate (int _, int _) {return 42;};

Console.WriteLine(&quot;constant(3,4)={0}&quot;,constant(3,4));

Понятие лямбда-выражений

Чтобы завершить знакомство с архитектурой событий .NET Core, необходимо исследовать лямбда-выражения. Как объяснялось ранее в главе, язык C# поддерживает возможность обработки событий "встраиваемым образом", позволяя назначать блок операторов кода прямо событию с применением анонимных методов вместо построения отдельного метода, который должен вызываться делегатом. Лямбда-выражения всего лишь лаконичный способ записи анонимных методов, который в конечном итоге упрощает работу с типами делегатов .NET Core.

1 ... 243 244 245 246 247 248 249 250 251 ... 642
На этой странице вы можете бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю бесплатно.
Похожие на Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю книги

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