- •Лекция 20, 21. Делегаты и события
- •Пример делегата для обычной функции
- •Пример делегата для метода класса
- •1.Делегат для выбора методов на этапе выполнения
- •Delegate.Invoke или что там внутри? (для продвинутых)
- •MulticastDelegate.GetInvocationList
- •Пример делегата для работы с несколькими методами
- •2. Делегат как оповещатель. Паттерн «наблюдатель»
- •Пример делегата для оповещения наблюдателей
- •3. Делегат как процедура обратного вызова
- •Пример передачи делегата в качестве параметра функции
- •4.Делегат, как обработчик событий
- •[Cпецификаторы] event тип делегата имя события, где
- •Пример делегата для оповещения наблюдателей с помощью событий
- •Стандартные делегаты
- •Пример стандартного делегата EventHandler для оповещения наблюдателей с помощью событий
Пример передачи делегата в качестве параметра функции
namespace ConsoleApplication1
{
delegate double MyDelegate(double x);
class Program
{
//в качестве параметров – делегат(вид функции), дапазон значений)
public static void Table(MyDelegate del, double x, double b)
{Console.WriteLine("=========X================Y==================");
while (x <= b)
{
//вызов функции через делегат
Console.WriteLine("|{0,8:0.000}|{1,8:0.000}|", x, del(x));
x += 1;
}
Console.WriteLine("---------------------------------------------");
}
static void Main(string[] args)
{Console.WriteLine("Таблица функции синуса: ");
//вызывается фунция sin(x)
//аналогично написать – new MyDelegate (Math.Sin)
Table(Math.Sin, -2, 2);
Console.WriteLine("Таблица любой функции,принимающей Любое double и возвращающей всегда 1!!!: ");
//АНОНИМНЫЙ МЕТОД!!!
Table(delegate(double x) { return 1;}, 0, 3);
Console.ReadKey();
}
}
}
4.Делегат, как обработчик событий
Событие – это элемент класса, позволяющий классу посылать другим объектам извещения об изменении своего состояния. При этом для этих объектов (наблюдателей) должны обрабатываться эти события. Обработка событий должна быть зарегистрирована в объекте - источнике.
Таким образом, механизм событий реализует паттерн ”наблюдатель”.
Такой паттерн можно еще назвать моделью “публикация-подписка” – один класс (источник, отправитель) сообщения публикует события, которые он может создавать, а другие классы (получатели, наблюдатели) подписываются на получение этих событий.
События тесно связаны с делегатами – с помощью делегатов вызываются обработчики событий.
Общий синтаксис объявления события:
[Cпецификаторы] event тип делегата имя события, где
спецификаторы – new,public,virtual,staticи др, причем событие может быть статическим (для класса) и обычным (для экземпляра класса)
event–ключевое слово.
тип делегата – это делегат, методы которого будут обрабатывать данное событие
Пример объявления события:
public delegate void My(object o);//объявление делегата
class A
{ public event My My_Event//объявление события My_Event
}
Алгоритм работы с событиями:
Объявление делегата, задающего сигнатуру методов – обработчиков событий
Объявление события внутри класса (источника)
Объявление и реализация метода, создаваемого событие
Объявление и реализация методов внутри классов (наблюдателей)– обработчиков события (привязанных к делегату). Их сигнатура должна совпадать с делегатом.
Каждый экземпляр класса, желающий получать сообщение о событии должен зарегистрировать в экземпляре источнике метод обработки события.
Пример делегата для оповещения наблюдателей с помощью событий
namespace ConsoleApplication1
{ public delegate void MyDelegate();
class Источник
{//событие – поле класса
public event MyDelegate My_event;
public void Создать_событие()
{ Console.WriteLine("Событие создано!!!");
//значение события по умолчанию null
if (My_event != null) My_event();
}
}
class Наблюдатель1
{ public void Do_Event_1()
{ Console.WriteLine("ВИЖУ, что произошло событие!!!"); }
}
class Наблюдатель2
{ public static void Do_Event_2()
{ Console.WriteLine("Я тоже ВИЖУ, что произошло событие!!!"); }
}
class Program
{static void Main(string[] args)
{ Источник A = new Источник();
Наблюдатель1 B = new Наблюдатель1();
Наблюдатель1 С = new Наблюдатель1();
//регистрация обработчиков событий
A.My_event += new MyDelegate(B.Do_Event_1);
A.My_event += new MyDelegate(С.Do_Event_1);
A.My_event += new MyDelegate(Наблюдатель2.Do_Event_2);
A.Создать_событие();
A.My_event -= new MyDelegate(B.Do_Event_1);
A.Создать_событие(); Console.ReadKey();
}
}
}
