Цель работы: Освоить применение делегатов и событий.

advertisement
Цель работы: Освоить применение делегатов и событий.
Многоадресная передача.
Одна из самых интересных возможностей делегата — поддержка
многоадресной передачи (multicasting). Выражаясь простым языком, многоадресная
передача — это способность создавать список вызовов (или цепочку вызовов)
методов, которые должны автоматически вызываться при вызове делегата. Такую
цепочку создать нетрудно.
Достаточно создать экземпляр делегата, а затем для добавления методов в эту цепочку
использовать оператор "+=".
Для удаления метода из цепочки используется оператор "-= ". Можно также для
добавления и удаления методов использовать в отдельности операторы "+", " - " и "=",
но чаще применяются составные операторы "+=" и "-=".
Методы, помещённые в такую цепочку, будут вызваться по очереди, согласно их
добавлению.
Ограничение: Делегат с многоадресной передачей имеет одно ограничение: он должен
возвращать тип void.
Рассмотрим пример оконного приложения.
privateclasstаlker
{
constint ff = 7;
//метод, выводящий на экран колличество делегатов в цепочке.
publicstaticvoid say(String say_t)
{
MessageBox.Show("in queue=" + say_t);
}
}
publicdelegatevoiddsay(String dstring); // обьявляем делегат
dsay dsayo; // производим первичное определение делегата, без инициализиции.
// кнопка, добавляющая метод в цепочку делегат.
privatevoid button1_Click(object sender, EventArgs e)
{
dsayo += newdsay(talker.say); // сам процессс добавления
dsayo(Convert.ToString(dsayo.GetInvocationList().Count())); // вызов делегата, то есть всей
цепочки методов.
}
//кнопка, удаляющая метод из делегата.
privatevoid button2_Click(object sender, EventArgs e)
{
dsayo -= newdsay(talker.say);
dsayo(Convert.ToString(dsayo.GetInvocationList().Count()));
}
События.
На основе делегатов построено еще одно важное средство С#: событие (event).
Событие — это автоматическое уведомление о выполнении некоторого действия.
События работают следующим образом. Объект, которому необходима информация о
некотором событии, регистрирует обработчик для этого события. Когда ожидаемое
событие происходит, вызываются все зарегистрированные обработчики. А теперь
внимание: обработчики событий представляются делегатами. События — это члены
класса, которые объявляются с использованием ключевого слова event. Наиболее
распространенная форма объявления события имеет следующий вид:
event событийный делегат объект;
Здесь элемент событийный делегат означает имя делегата, используемого для
поддержки объявляемого события, а элемент объект — это имя создаваемого
событийного объекта.
Рассмотрим пример:
using System;
// Объявляем делегат для события,
delegate void MyEventHandler();
// Объявляем класс события,
class MyEvent
{
public event MyEventHandler SomeEvent;
// Этот метод вызывается для генерирования события,
public void OnSomeEvent()
{
if(SomeEvent != null)
SomeEvent();
}
}
class EventDemo
{
// Обработчик события,
static void handler()
{
Console.WriteLine("Произошло событие.");
}
public static void Main()
{
MyEvent evt = new MyEvent();
// Добавляем метод handler() в список события,
evt.SomeEvent += new MyEventHandler(handler);
// Генерируем событие,
evt.OnSomeEvent();
}
}
// конец
При выполнении программа отображает следующие результаты:
Произошло событие.
Все события активизируются посредством делегата. Следовательно, событийный
делегат определяет сигнатуру для события. В данном случае параметры отсутствуют,
однако событийные параметры разрешены. Поскольку события обычно
предназначены для многоадресной передачи, они должны возвращать значение типа
void. Обратите внимание на то, что обработчик события вызывается только в том
случае, если делегат SomeEvent не равен null-значению. Поскольку другие части
программы, чтобы получить уведомлении о событии, должны зарегистрироваться,
можно сделать так, чтобы метод OnSomeEvent () был вызван до регистрации любого
обработчика события. Чтобы предотвратить вызов null-объекта. Внутри класса
EventDemo создается обработчик события handler(). В этом примере обработчик
события просто отображает сообщение, но ясно, что другие обработчики могли бы
выполнять более полезные действия.
Задание 1:
Реализовать оконное приложение с кнопкой "talk" и полем ввода текста. Реализовать
класс Talker, содержащий метод Say, принимающий строку из поля ввода и
производящий вывод ее на экран. Добавить в класс формы поле-делегат. При нажатии
на кнопку "talk" на форме должен производиться вызов метода Talkrer.Say при
помощи делегата и передача ему строки, введенной в поле ввода. Добавить в
приложение класс Writer, содержащий метод Write, принимающий строку и
производящий запись этой строки в файл "log.txt". Добавить на форму кнопку "write",
нажатие на которую приводило бы к добавлению делегата, ссылающегося на метод
Writer.Write к уже существующему. Добавить еще одну кнопку - "call delegate", и
перенести вызов делегата в метод-обработчик нажатия на эту кнопку.
Модифицировать задание так, чтобы при нажатии на кнопку "call delegate" на форме
вырабатывалось пользовательское событие MyEvent, на которое по нажатии кнопок
"talk" и "write" подписываются соответственно методы Talkrer.SayHi и Writer.Write.
Задание 2:
Реализовать оконное приложение, демонстрирующее работу многоадресной передачи.
Создать кнопки Add и Delete, добавляющие и удаляющие методы в цепочку вызовов
соответственно.
Указание: взять за основу приведенный пример, добавить обработчики ошибок.
Цепочка методов должна собирать строку из слов в поле на форме и выводить
полученную строку на экран, используя MessageBox один раз. Информировать
пользователя о количестве методов в цепочке.
Полезные ссылки:
http://rsdn.ru/article/dotnet/delegat.xml
Download