Шрифт:
Интервал:
Закладка:
{
/// Если этот автомобиль сломан, то отправить сообщение об этом.
if (_carIsDead)
{
_listOfHandlers?.Invoke("Sorry, this car is dead...");
}
else
{
CurrentSpeed += delta;
// Автомобиль почти сломан?
if (10 == (MaxSpeed - CurrentSpeed))
{
_listOfHandlers?.Invoke("Careful buddy! Gonna blow!");
}
if (CurrentSpeed >= MaxSpeed)
{
_carIsDead = true;
}
else
{
Console.WriteLine("CurrentSpeed = {0}", CurrentSpeed);
}
}
}
Обратите внимание, что при попытке вызова методов, поддерживаемых переменной-членом _listOfHandlers, используется синтаксис распространения null. Причина в том, что создание таких объектов посредством вызова вспомогательного метода RegisterWithCarEngine() является задачей вызывающего кода. Если вызывающий код не вызывал RegisterWithCarEngine(), а мы попытаемся обратиться к списку вызовов делегата, то получим исключение NullReferenceException во время выполнения. Теперь, когда инфраструктура делегатов готова, внесите в файл Program.cs следующие изменения:
using System;
using CarDelegate;
Console.WriteLine("** Delegates as event enablers **n");
<b>// Создать объект Car.</b>
Car c1 = new Car("SlugBug", 100, 10);
<b>// Сообщить объекту Car, какой метод вызывать,</b>
<b>// когда он пожелает отправить сообщение.</b>
c1.RegisterWithCarEngine(
new Car.CarEngineHandler(OnCarEngineEvent));
<b>// Увеличить скорость (это инициирует события).</b>
Console.WriteLine("***** Speeding up *****");
for (int i = 0; i < 6; i++)
{
c1.Accelerate(20);
}
Console.ReadLine();
<b>// Цель для входящих сообщений.</b>
(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})static void OnCarEngineEvent(string msg)
{
Console.WriteLine("n*** Message From Car Object ***");
Console.WriteLine("=> {0}", msg);
Console.WriteLine("********************n");
}
Код начинается с создания нового объекта Car. Поскольку вас интересуют события, связанные с двигателем, следующий шаг заключается в вызове специальной регистрационной функции RegisterWithCarEngine(). Вспомните, что метод RegisterWithCarEngine() ожидает получения экземпляра вложенного делегата CarEngineHandler, и как в случае любого делегата, в параметре конструктора передается метод, на который он должен указывать. Трюк здесь в том, что интересующий метод находится в классе Program! Обратите также внимание, что метод OnCarEngineEvent() полностью соответствует связанному делегату, потому что принимает string и возвращает void. Ниже показан вывод приведенного примера:
***** Delegates as event enablers *****
***** Speeding up *****
CurrentSpeed = 30
CurrentSpeed = 50
CurrentSpeed = 70
***** Message From Car Object *****
=> Careful buddy! Gonna blow!
***********************************
CurrentSpeed = 90
***** Message From Car Object *****
=> Sorry, this car is dead...
***********************************
Включение группового вызова
Вспомните, что делегаты .NET Core обладают встроенной возможностью группового вызова. Другими словами, объект делегата может поддерживать целый список методов для вызова, а не просто единственный метод. Для добавления нескольких методов к объекту делегата вместо прямого присваивания применяется перегруженная операция +=. Чтобы включить групповой вызов в классе Car, можно модифицировать метод RegisterWithCarEngine():
public class Car
{
<b> // Добавление поддержки группового вызова.</b>
<b> // Обратите внимание на использование операции +=,</b>
<b> // а не обычной операции присваивания (=).</b>
public void RegisterWithCarEngine(
CarEngineHandler methodToCall)
- Понимание SQL - Мартин Грубер - Базы данных