Делегаты. Разобраться на примере - C#
Формулировка задачи:
Пытаюсь вкурить Троелсона с его разъяснением делегатов. У Шильдта все проще у Рихтера все сложнее.
В общем есть по которому я уже прошелся с комментариями как мог, но ясность не пришла.
Итак
ну и MAIN
как это получается не понимаю когда у них проходит взаимосвязь???
если из метода мы вышли и в майне вошли в цикл
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace delegateTroelson
{
//1. Создали класс в проекте delegateTroelson
class Car
{
//2. Объявили поля
public int CurrentSpeed { get; set; } //3.1. Описали свойства для полей
public int MaxSpeed { get; set; } //3.2. Описали свойства для полей
public string PetName { get; set; } //3.3. Описали свойства для полей
private bool carIsDead; //3.4 булевая переменная (свойства не нужны)
// 4.Описали конструкторы класса.
public Car() { MaxSpeed = 100; } //4.1 Конструктор без параметров
public Car(string name, int maxSp, int currSp)//4.2. Конструктор с параметрами
{
CurrentSpeed = currSp;
MaxSpeed = maxSp;
PetName = name;
}
// 5. Объявили тип делегата.
public delegate void CarEngineHandler(string msgForCaller);//5.1. тип данного делегата принимает стринг возвращает void
// 6. Определить переменную-член типа этого делегата.
private CarEngineHandler listOfHandlers; //6.1. Данная переменная объявлена как privat чтобы защитить код извне(инкапсуляция)
// 7. создали метод который через предоставить доступ к закрытой переменной listOfHandlers
public void RegisterWithCarEngine(CarEngineHandler methodToCall) //7.1. Метод принимает как входной параметр член делегата
{
listOfHandlers = methodToCall;
}
//8. Реализовать метод Accelerate()-ускорение который принимает int
public void Accelerate(int delta)
{
//8.1. Если этот автомобиль сломан, отправить сообщение об этом.
if (carIsDead) //если carIsDead==true
{
if (listOfHandlers != null) //делаем проверку listOfHandlers
listOfHandlers("Sorry, this car is dead...");
}
else
{
CurrentSpeed += delta; //в данном примере в Main объявлен класс с параметром с.CurrentSpeed=10 а
//значение равно 20, то есть на первом проходе for в Main CurrentSpeed равна 30
//макс скорость объявлена в конструкторе 100,
if (10 == (MaxSpeed - CurrentSpeed) && listOfHandlers != null) //на первом проходе i-того условие не выполняется
{
listOfHandlers("Careful buddy! Gonna blow!"); //на 1-ой i-терации проходим дальше
}
if (CurrentSpeed >= MaxSpeed)
//на первой i-терации CurrentSpeed=30 а MaxSpeed=100 условие не выполняется
carIsDead = true;
else
//на первой итерации условие выполнилось, вывели на экран
Console.WriteLine("CurrentSpeed= {0}", CurrentSpeed);
}
}
}
}using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace delegateTroelson
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("***** Delegates as event enablers *****\n");
//9. создать объект Car.
Car cl = new Car("SlugBug", 100, 10); //инициировали конструктором
//вызываем метод RegisterWithCarEngine, по сути этот метод дает нам доступ к закрытой переменной
//но как параметр этого метода мы передаем delegate, который соответствует сигнатуре void МЕТОД(string) объявленный в классе Main как OnCarEngineEvent
cl.RegisterWithCarEngine(new Car.CarEngineHandler(OnCarEngineEvent)); //ПОЧЕМУ ДЕЛЕГАТ реализуется ЗДЕСЬ
// Ускорить (это инициирует события).
Console.WriteLine("***** Speeding up *****");
for (int i = 0; i < 6; i++) //А ВЫПОЛНЯЕТСЯ ЗДЕСЬ???
//на 5-ой итерации у меня отрабатывает метод OnCarEngineEvent
cl.Accelerate(20);
Console.ReadLine();
}
// Это цель для входящих сообщений.
public static void OnCarEngineEvent(string msg)
{
Console.WriteLine("\n***** Message From Car Object *****");
Console.WriteLine("=> {0}", msg);
Console.WriteLine("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n");
}
}
}Решение задачи: «Делегаты. Разобраться на примере»
textual
Листинг программы
private CarEngineHandler listOfHandlers;