Делегаты Как созданные объекты могут посылать сообщения тем объектам, которые их породили? При программировании под Windows на С и C++ основное средство.

Презентация:



Advertisements
Похожие презентации
ДЕЛЕГАТЫ Лекция 7 1. Зачем нужны делегаты 2 И данные, и код располагаются в памяти компьютера по определенным адресам. Передача адресов данных в C# происходит.
Advertisements

События События Важная роль делегатов заключается в том, что на них основана модель событий С#. Применение событий вовсе не ограничено приложениями с графическим.
Высокоуровневые методы информатики и программирования Лекция 9 Делегаты.
В С# предусмотрены средства для создания пользовательских классов-контейнеров, к внутренним элементам которых можно обращаться при помощи того же оператора.
Создание клонируемых объектов (интерфейс IClonable)
Классы в С#. Перечисления С# Перечисление задает конечное множество возможных значений, которые могут получать объекты класса перечисление. [атрибуты][модификаторы]
Высокоуровневые методы информатики и программирования Лекция 10 События.
Наследование Наследование – это отношение является между классами. class Person { string first_name; int birth_year;... } class Student : Person { float.
Учебный курс Объектно-ориентированный анализ и программирование Лекция 7 Методы как средство реализации операций Лекции читает кандидат технических наук.
ИТЕРАТОРЫ И LINQ Лекция 1. Интерфейс IEnumerable и IEnumerator Любая коллекция реализует интерфейс IEnumerable. public interface IEnumerable : IEnumerable.
АССОЦИАТИВНЫЕ КОЛЛЕКЦИИ Лекция 6 1. Отличие от последовательных 2 В последовательной коллекции каждый элемент ассоциируется с номером, начиная с 0. В.
©Павловская Т.А. (СПбГУ ИТМО) Курс «С#. Программирование на языке высокого уровня» Павловская Т.А.
С# и ООП Формальное определение класса с C# Класс в C# - это пользовательский тип данных (user defined type), который состоит из данных (часто называемых.
САОД кафедра ОСУ 1 Основные абстрактные типы данных Схема процесса создания программ для решения прикладных задач ВУ.
Перегрузка операторов x = a + b результат 1-й операнд2-й операнд оператор По количеству операндов операторы делятся на: унарные (один операнд) бинарные.
Высокоуровневые методы информатики и программирования Лекция 14 Интерфейсы.
Делегаты Делегат эти объект, который безопасно инкапсулирует метод, его действие схоже с указателем функции в C и C++. Делегаты используются для передачи.
Коллекции классов Лекция 12. С помощью коллекций вместо создания структур данных программист использует готовые структуры данных, не заботясь об их реализации.
Массивы в С#. Массивом называют упорядоченную последовательность элементов одного типа. Каждый элемент массива имеет индексы, определяющие порядок элементов.
ПОТОКИ Начальные сведенияПОТОКИ Начальные сведения.
Транксрипт:

Делегаты

Как созданные объекты могут посылать сообщения тем объектам, которые их породили? При программировании под Windows на С и C++ основное средство для решения этой проблемы это функция обратного вызова (callback function, или просто callback), которая основана на использовании указателей на функции в oпeративной памяти.

Делегаты Делегат выполняет те же действия, что и указатель на функцию, но способами гораздо более безопасными и лучше соответствующими принципам объектно- ориентированного программирования. Как и все в мире С#, делегат это специальный класс. Любой делегат производится от единого базового класса System.MulticastDelegate

Делегаты public delegate void PlayAcidHouse (object PaulQakenfold, int volume); На самом деле: public class PlayAcidHouse : System.MulticastDelegate { PlayAcidHouse(object target, int ptr); // Синхронный метод Invoke() public void virtual Invoke(object PaulOakenfold, int volume); // Асинхронная версия того же самого обратного вызова public virtual lAsyncResult Beginlnvoke (object PaulOakenfold, int volume, AsyncCallback cb, object o); public virtual void Endlnvoke(IAsyncResult result); }

Пример делегата // Класс Саг вновь изменился public class Car { // Новые переменные! private bool isDirty; // Испачкан ли наш автомобиль? private bool shouldRotate; // Нужна ли замена шин? // Конструктор с новыми параметрами public Car(string name, int max, int curr, bool dirty, bool rotate) {… isDirty = dirty; shouldRotate = rotate; } // Свойство для isDirty public bool Dirty { get { return isDirty; } set { isDirty = value;} } // Свойство для shouldRotate public bool Rotate {get { return shouldRotate; } set { shouldRotate = value; } }}

Пример делегата // Делегат - это класс, инкапсулирующий указатель на функцию. В нашем случае // этой функцией должен стать какой-то метод, принимающий в качестве параметра // объект класса Саг и ничего не возвращающий; public delegate void CarDelegate(Car с); Делегат может быть определен внутри другого класса // Помещаем определение делегата внутрь определения класса public class Car : Object ( // Теперь наш делегат получит служебное имя Car$CarDelegate, то есть станет // вложенным типом... public delegate void CarDelegate(Саг с);... }

Члены System.MulticastDelegate Таблица 5.2. Некоторые унаследованные члены делегатов Method - Это свойство возвращает имя метода, на который указывает делегат Target - Если делегат указывает на метод член класса, то этот член возвращает имя этого класса. Если Target возвращает значение типа null, то делегат указывает на статический метод Combine() - Этот статический метод используется для создания делегата, указывающего на несколько разных функций GetlnvocationList() - Возвращает массив типов Delegate, каждый из которых представляет собой запись во внутреннем списке указателей на функции делегата Remove() - Этот статический метод удаляет делегат из списка указателей на функции

Применение CarDelegate // В классе Garage предусмотрен метод, принимающий CarDelegate в качестве параметра public class Garage { ArrayList theCars = new ArrayList(); // Набор машин в гараже public Garage() // Создаем объекты машин в гараже { theCars.Add(new car(Viper, 100, 0, true, false)); theCars.Add(new car("Fred, 100, 0, false, false)); theCars.Add(new car("BillyBob, 100, 0, false, true)); theCars.Add(new car(Bart, 100, 0, true, true)); theCars.Add(new car("Stan, 100, 0, false, true)); }

Применение CarDelegate // Можно считать, что ргос - это эквивалент указателя на функцию public void ProcessCars(Car.CarDelegate proc) { // Интересно, а куда мы передаем наш вызов? Console.WriteLine(***** Calling: {0} *****, proc.Method.ToString()); // Еще одна проверка: вызываемый метод является статическим или обычным? if (proc. Target != null) Console. WriteLine("->Target: {0}, proc.Target.ToString()): else Console. WriteLine("->Target Is a static method"); // Для чего это все затевалось: при помощи делегата вызываем метод // и передаем ему все объекты Саг foreach (car с in theCars) ргос(с); }

Применение CarDelegate // Гараж передает право выполнить всю работу этим статическим функциям - наверное, у него нет хороших механиков... public class CarApp { public static void WashCar(Car с) // Первый метод, на который будет указывать делегат {If (с.Dirty) { Console.WriteLine("Cleaning a car"); с.Dirty=false; } else Console.WriteLine("This car is already clean..."); ) public static void RotateTires(Car c) // Второй метод для делегата { if(c.Rotate) { Console.WriteLine(Tires have been rotated"); c.Rotate=false; } else Console.WriteLine("Don't need to be rotated..."); } public static int Main(string[] args) { // Создаем объект Garage Garage g = new Garage(); // Моем все грязные машины g.ProcessCars(new Car.CarDelegate(WashCar)); II Меняем шины g.ProcessCars(new Car.CarDelegate (RotateTires)) ; return 0; }

Многоадресность Многоадресный делегат это объект, который может содержать в себе сразу несколько указателей на функции. // Добавляем во внутренний список указателей делегата сразу два указателя на функции: public static int Main(string[] args) { // Создаем объект Garage Garage g = new Garage(): // Создаем два новых делегата Car.CarDelegate wash = new Car.CarDelegate(WashCar): Car.CarDelegate rotate = new Car.CarDelegate(RotateTires); // Чтобы объединить два указателя на функции в многоадресном делегате, // используется перегруженный оператор сложения (+). В результате создается новый // делегат, который содержит указатели на обе функции g.ProcessCars(wash + rotate); return 0: }

Многоадресность Изменяем функцию ProcessCars public void ProcessCars (CarDelegate proc) { // Куда мы передаем вызов? foreach (Delegate d in proc.GetInvocationList()) { Console.WriteLinet"***** Calling: " + d.method.ToString() + " *****");... }

Делегаты, указывающие на обычные функции // Статические функции перестали быть статическими и переместились // во вспомогательный класс public class ServiceDept { // Уже не статическая! public void WashCar(Car с) { if(c.Dirty) Console.WriteLine('Cleaning a car"); else Console.WnteLine(This car is already clean...); } // To же самое public void RotateTires(Car c) { If(c.Rotate) Console.WriteLine(Tlres have been rotated"); else Console.WriteLine(Don't need to be rotated..."); }

Делегаты, указывающие на обычные функции // Делегаты будут указывать на обычные методы класса ServiceDept public static int Main(string[] args) { // Создаем гараж Garage g = new Garage(); II Создаем отдел обслуживания ServlceDept sd = new ServiceDept(); // Гараж делегирует работу отделу обслуживания Car.CarDelegate wash = new Car.CarDelegate(sd.WashCar); Car.CarDelegate rotate = new Car.CarDelegate(sd.RotateTires); MulticastDelegate d = wash + rotate; // Обращаемся в гараж с просьбой сделать эту работу g.ProcessCars(Car.CarDelegate)d); return 0; }