Чтение онлайн

ЖАНРЫ

Язык программирования C#9 и платформа .NET5
Шрифт:

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

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

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

Обратите внимание, что при обработке первого события

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

c1.AboutToBlow += delegate

{

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

};

Строго

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

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

{

aboutToBlowCounter++;

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

};

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

{

aboutToBlowCounter++;

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

};

...

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

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

{

c1.Accelerate(20);

}

Console.WriteLine("AboutToBlow event was fired {0} times.",

aboutToBlowCounter);

Console.ReadLine;

После запуска модифицированного кода вы обнаружите, что финальный вывод

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("Eek! Going too fast!");

};

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

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

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

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

Например, в следующем коде создается делегат

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

Поделиться с друзьями: