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

Шрифт:

-
+

Интервал:

-
+

Закладка:

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

public class Car

{

...

  public event EventHandler<CarEventArgs> Exploded;

  public event EventHandler<CarEventArgs> AboutToBlow;

}

Затем в вызывающем коде тип EventHandler<CarEventArgs> можно использовать везде, где ранее указывался CarEngineHandler (или снова применять групповое преобразование методов):

Console.WriteLine("***** Prim and Proper Events *****n");

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

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

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

c1.AboutToBlow += CarIsAlmostDoomed;

c1.AboutToBlow += CarAboutToBlow;

EventHandler<CarEventArgs> d = CarExploded;

c1.Exploded += d;

...

Итак, к настоящему моменту вы узнали основные аспекты работы с делегатами и событиями в С#. Хотя этого вполне достаточно для решения практически любых задач, связанных с обратными вызовами, в завершение главы мы рассмотрим несколько финальных упрощений, в частности анонимные методы и лямбда-выражения.

Понятие анонимных методов C#

Как было показано ранее, когда вызывающий код желает прослушивать входящие события, он должен определить специальный метод в классе (или структуре), который соответствует сигнатуре ассоциированного делегата. Ниже приведен пример:

SomeType t = new SomeType();

// Предположим, что SomeDeletage может указывать на методы,

// которые не принимают аргументов и возвращают void.

t.SomeEvent += new SomeDelegate(MyEventHandler);

// Обычно вызывается только объектом SomeDelegate.

static void MyEventHandler()

{

  // Делать что-нибудь при возникновении события.

}

Однако если подумать, то такие методы, как MyEventHandler(), редко предназначены для вызова из любой другой части программы кроме делегата. С точки зрения продуктивности вручную определять отдельный метод для вызова объектом делегата несколько хлопотно (хотя и вполне допустимо).

Для решения указанной проблемы событие можно ассоциировать прямо с блоком операторов кода во время регистрации события. Формально такой код называется анонимным методом. Чтобы ознакомиться с синтаксисом, создайте новый проект консольного приложения по имени AnonymousMethods, после чего скопируйте в него файлы Car.cs и CarEventArgs.cs из проекта CarEvents (не забыв изменить пространство имен на AnonymousMethods). Модифицируйте код в файле Program.cs, как показано ниже, для обработки событий, посылаемых из класса Car, с использованием анонимных методов вместо специальных именованных обработчиков событий:

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

using System;

using AnonymousMethods;

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

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

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

c1.AboutToBlow += delegate

{

  Console.WriteLine("Eek! Going too fast!");

};

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

{

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

};

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

{

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

};

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

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

{

  c1.Accelerate(20);

}

Console.ReadLine();

На заметку! После финальной фигурной скобки в анонимном методе должна быть помещена точка с запятой, иначе возникнет ошибка на этапе компиляции.

И снова легко заметить, что специальные статические обработчики событий вроде CarAboutToBlow() или CarExploded() в вызывающем коде больше не определяются. Взамен с помощью синтаксиса += определяются встроенные неименованные (т.е. анонимные) методы, к которым вызывающий код будет обращаться во время обработки события. Базовый синтаксис анонимного метода представлен следующим псевдокодом:

НекоторыйТип t = new НекоторыйТип();

t.НекотороеСобытие += delegate (необязательноУказываемыеАргументыДелегата)

{ /* операторы */ };

Обратите внимание, что при обработке первого события AboutToBlow внутри предыдущего примера кода аргументы, передаваемые из делегата, не указывались:

c1.AboutToBlow += delegate

{

  Console.WriteLine("Eek! Going too fast!");

};

Строго говоря, вы не обязаны принимать входные аргументы, отправленные специфическим событием. Но если вы хотите задействовать эти входные аргументы, тогда понадобится указать параметры, прототипированные типом делегата (как показано во второй обработке событий AboutToBlow и Exploded). Например:

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

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