Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Н.Р. Бухараев (3 семестр)(ООП в интегрированной...doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.41 Mб
Скачать

Событийный стиль в процедурном программировании - управление данными (на примере)

Пример (животные):

Задача: Описывается вызов движения блохи. Как только блоха начинает движение, все динозавры начинают кричать: «Ай-яй-яй». Нужно заметить, что явного вызова того, чтобы динозавры кричали, нет (но этот вызов где-то прошит). Событием здесь является то, что блоха движется, а динозавры кричат.

Замечание:

Блоха- отправитель сообщений, а TRex-ы – слушатели.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace Animals

{

class cAnimal

{

.

.

.

}//class cAnimal

//класс "cDinosaur" наследник класса "сAnimal"

public class cDinosaur : cAnimal

{

.

.

.

} //class cDinosaur

class cTRex : cDinosaur

{

.

.

.

//обработка событий - слушатель (listener) события FleaJumpEvent

private cFlea FleaJumpSender; // Flea To Listen To- поле, в котором хранится ссылка на блоху, а FleaJumpSender-Отправитель

public void SetFleaJumpSender(cFlea x) // получает ссылку на эту блоху

{

FleaJumpSender = x; // запоминание источника события

//Итак, блоха нужна для того, чтобы получить лист (список слушателей), который при ней хранится.

FleaJumpSender.FleaJumpEventList += new cFlea.FleaJumpEventHandler(TRexFleaJumpEventHandler);// добавление в список ссылки на свой обработчик

// new- создаётся новая копия описанной переменной функционального типа. После новое значение этого типа добавляется в список.

// += -это бинарное присваивание (т.е. имя списка и в левой, и в правой частях присваивания)

// аналогично осуществляется отказ от подписки "-="

}

public void TRexFleaJumpEventHandler(cFlea Sender)

{

Console.WriteLine(GetName() + "afraid of" + Sender.GetName() + "jumping");

}

} // class cTRex

// класс "Flea" наследник класса "cAnimal"

class cFlea : cAnimal //производный класс "Блоха"

{

.

.

.

public override void Move() // описание метода "двигаться" для блох

{

Console.WriteLine(GetName() + "jumps");

OnFleaJump(); // кратный вызов

}

.

.

.

}

}

Событийное программирование в c# (delegate, event)

Delegate - функциональный тип, к которому относятся любые функции, принимающие на вход параметр типа блоха (т.е. cFlea Sender) и возвращающие функции.

Таким образом, к этому типу относятся все функции с определённым списком параметров.

Event - событие- объявление переменной списка ссылок ранее объявленного типа

class cFlea

{

.

.

.

// обработка событий-источник/ sender(Отправитель)

// организация обработки события FleaJumpEvent

public delegate void FleaJumpEventHandler(cFlea Sender); // типизированая ссылка на функцию- обработчик- заголовок

//-объявление функционального типа с именем FleaJumpEventHandler- типизированная ссылка на функцию, но не на тип данных

EventHandler- пользовательское соглашение- обработчик событий,

FleaJump-прыжок блохи

public event FleaJumpEventHandler FleaJumpEventList; // связь имени события с его обработчиками (реализация- список ссылок на обработчики)

//список называется FleaJumpEventList, содержит он ссылки типа FleaJumpEventHandler

//кратный вызов - применение объявленного списка к нужному аргументу (обработчиков)

protected virtual void OnFleaJump() //protected, т.к. события не вызываются извне

//OnFleaJump- по прыжку блохи-стандартное соглашение для методов такого назначения

{ // проверка на пустоту списка

if (FleaJumpEventList != null) FleaJumpEventList(this); // если список не является пустым, то применяем его (список) к this (т.е. блоха в качестве сообщения пересылает ссылку на себя), передавая значения полей

// Таким образом, не функция применяется к аргументу, а список функциональных ссылок (т.е. по ссылкам "дёргаются" функции, которые применяются поочерёдно к списку аргументов)

}

//теперь везде, где прыгает блоха, вызывается метод OnFleaJump

//OnFleaJump нужно вызвать в методе Move

} //class cFlea

class cProgram

{

static void Main()

{

cDinosaur Dino = new cDinosaur("Dino");

cFlea Bug = new cFlea("Bug");

Bug.Attacks(Dino); // полиморфный вызов- неявное уточнение типа cAnimal

Console.WriteLine("______________________");

//аналогично

// Dino.cAnimal x;

// x=Dino; // уточнение типа не требует явного преобразования типа

// Bug. Attacks(x);

// отследи вызов последней реализации

cTRex Rex = new cTRex("Rex");

Bug.Attacks(Rex);

Console.WriteLine("______________________");

//обработка событий

cTRex AnotherRex = new cTRex("Another Rex");

Rex.SetFleaJumpSender(Bug); //вызывается метод set, в котором говорится о том, чтобы Rex слушал Bug

AnotherRex.SetFleaJumpSender(Bug); //AnotherRex слушал Bug

Bug.Move(); //движение блохи (в этом методе есть OnFleaJump, который вызывает методы всех динозавров)

Console.ReadKey(); //задержка

}

}

}

Производится распечатка имени динозавра и демонстрация того, что динозавр боится прыжков блохи (выдаётся имя конкретной блохи).

Таким образом, public delegate void FleaJumpEventHandler(cFlea Sender); -объявление функционального типа (указатель на все функции данного типа, аргументами (параметрами) которых служит блоха)- не является заголовком функции.

delegate void FleaJumpEventHandler(cFlea Sender) понимается так:

-заводится новый тип для создания списка ссылок такого типа

-именуется