Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю
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
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