- •Лекция 20, 21. Делегаты и события
- •Пример делегата для обычной функции
- •Пример делегата для метода класса
- •1.Делегат для выбора методов на этапе выполнения
- •Delegate.Invoke или что там внутри? (для продвинутых)
- •MulticastDelegate.GetInvocationList
- •Пример делегата для работы с несколькими методами
- •2. Делегат как оповещатель. Паттерн «наблюдатель»
- •Пример делегата для оповещения наблюдателей
- •3. Делегат как процедура обратного вызова
- •Пример передачи делегата в качестве параметра функции
- •4.Делегат, как обработчик событий
- •[Cпецификаторы] event тип делегата имя события, где
- •Пример делегата для оповещения наблюдателей с помощью событий
- •Стандартные делегаты
- •Пример стандартного делегата EventHandler для оповещения наблюдателей с помощью событий
Лекция 20, 21. Делегаты и события
Делегат – особый вид класса, хранящий ссылки на методы.
Делегат– класс (ссылочный тип), инкапсулирующий (содержащий в себе) метод с указанной сигнатурой и возвращаемым типом.
Все делегаты являются объектами типа System.Delegate или System.MulticastDelegate.
Общий синтаксис объявления делегата:
[cпецификаторы]delegateтип возвращаемого значения метода имя делегата ([параметры]), где
delegate –ключевое слово.
тип возвращаемого значения– это тот тип, который будет возвращать функция, на которую ссылается делегат.
параметры – это необязательные параметры, которые будут присутствовать у функции, на которую ссылается делегат.
Примеры объявления делегата:
delegate void MyDelegate(string s); //делегат, который может работать для всех методов, которые возвращают тип void и имеют один строковый параметр.
public delegate int mydel();
delegate double MyD (double x);
//”Почти универсальный делегат”
delegate void My (object o)
Алгоритм работы с делегатом:
Объявление делегата;
Определение метода, “подходящего” для работы с делегатом
В основной программе создание экземпляра делегата и связь его с определённой функцией;
Вызов метода через делегат.
Делегат может быть применён:
Для обычной функции без класса;
Для метода внутри класса.
Пример делегата для обычной функции
class Program
{
//объявление делегата
delegate void MyDelegate(string s);
static void Myfunc(string s)
{
Console.WriteLine(s);
}
static void Main(string[] args)
{
//в конструкторе передается ссылка на функцию, которая делегируется (связыватся с делегатом)
MyDelegate del = new MyDelegate(Myfunc);//создание экземпляра делегата
del("Hello World");//вызов функции через делегат
Console.ReadKey();
}
}
Пример делегата для метода класса
namespace ConsoleApplication1
{
class my
{
public string mystring;//поле класса
public void Myfunc(string s)
{
// Вывод значения поля mystring, а также аргумента, переданного методу.
Console.WriteLine(mystring + s);
}
}
class Program
{
//объявление делегата
delegate void MyDelegate(string s);
static void Main(string[] args)
{
// Создадим экземпляр тестового класса.
my A = new my();
// Создадим экземпляр делегата, содержащего, помимо ссылки на сам метод, также ссылку
// на объект, для которого будет вызван метод.
MyDelegate del = new MyDelegate(A.Myfunc);
// Изменяем значение поля тестового объекта.
A.mystring = "Hello, World!";
// Вызовем метод через делегат.
del(" - from Delegate");
// Эквивалентен следующему вызову
// A.Myfunc(" - from Instance Delegate");
// Снова изменим значение поля тестового объекта.
A.mystring = "Good bye, World!";
// Снова обратимся к методу.
del(" - from Delegate");
Console.ReadKey(); } }}
Операции с делегатами: =,!=, +=,-=,= =.
Делегаты можно сравнивать на равенство и неравенство. Два делегата равны, если они оба не содержат ссылок на методы, или если они содержат ссылки на одни и те же методы в одном и том же порядке. Сравнивать можно даже делегаты различных типов при условии, что они имеют один и тот же тип возвращаемого значения и одинаковые списки параметров.
С делегатами одного типа можно выполнить операции простого и сложного присваивания: =, +=,-=.
Использование делегатов
Существует 4 вида использования делегатов:
Делегат для выбора методов делегирования(программист не знает, какой метод ему понадобится и задаёт или определяет его во время выполнения программы);
Делегат – оповещатель наблюдателя(паттерн “наблюдатель”);
Делегат, как обратный вызов метода;
Делегат, как обработчик событий.Обычно события обрабатываются не простыми методами, а делегатами. Событие генерирует идею “произошло нечто важное”, и программа должна на него отреагировать. События и делегаты являются тесно связанными понятиями, поскольку обработка событий требует точного выбора обработчика. Обработчик события реализуется на языке С#, как правило, в виде делегата.