L_OOP_2_17.pptx
- Количество слайдов: 13
Делегати
Одиночний делегат Посилання на функції n Зворотній виклик Host Виклики функцій Зворотній виклик n При роботі с Win API n Slave (нічого не знає про host) Функція зворотнього виклику (Callback) С, С++ n n n Виклик глобальних функцій Виклик статичних функцій Виклик функцій об’єкта. Необхідне посилання на об’єкт.
Делегат n Делегат – об'єкт, безпечний по відношенню до об'єкт типів, що вказують на метод n Містить: n n посилання на метод n жорстко визначає типи і кількість параметрів методу n n посилання на об'єкт жорстко визначає тип значення, що повертається Може вказувати на статичний метод чи метод екземпляра n Якщо посилання на обєкт дорівнює null, то це значить, що метод, якмй викликається є статичним n Забезпечує зворотній виклик n Виклик делегата синтаксично такий же як виклик звичайної функції
Робота з делегатами 1. Об'явити (описати) делегат n 2. Описати тип делегата, використовуючи спеціальний синтаксис (описати клас) Створити екземпляр делегата • • Виклик конструктора • 3. Об'явлення звичайної змінної типу Передача конструктору посилання на метод екземпляра або статичний метод Викликати делегат
Об'явлення типу делегата n Синтаксис [attributes] [modifiers] delegate return-typename(args-list); n n n схоже на визначення абстрактного метода, але це визначення типу жорстко задає сигнатуру метода, що викликається Приклади public delegate double Function 2 d(double x, double y); public delegate Complex. Function(Complex z); public delegate void Event. Handler(object o, Event. Args e);
n Приклад: public delegate double Process. Results(double x, double y); n За лаштунками (створюється клас - нащадок від Multicast. Delegate) public sealed class Process. Results : System. Multicast. Delegate { public Process. Results (object target, uint func. Adress); // для розуміння public object Target { get; } public Method. Info Method { get; } public double Invoke (double x, double y); // Сигнатура співпадає …. . } n Виклик делегата синтаксично такий же як виклик звичайної функції, але реально буде викликатися метод Invoke n Створюються ще методи Begin. Invoke() і End. Invoke() для асинхронного виклику метода n Самостійно не можна створити клас - нащадок від Multicast. Delegate або від Delegate. Тільки через синтаксис delegate
Створення (екземпляра) делегата n При створенні потрібно зв'язати з методом, що викликається (передати в конструктор) n Для метода екземпляра n n Для статичного метода n n Process. Results del = new Process. Results(object. Name. Function); Process. Results del = new Process. Results(type. Name. Function); Скорочений запис • • n Process. Results del = object. Name. Function; Process. Results del = type. Name. Function; Сигнатура метода і делегата повинна співпадати
Виклик делегата n Як і виклик звичайної функції, де як функція, що викликається, вказується екземпляр делегата double d = del(x, y); double d = del(4+12, 37); n Викликати метод Invoke не рекомендується, але і не забороняється. В деяких випадках це необхідно. double d = del. Invoke(4+12, 37);
Делегати як параметри функції n Делегати можна використовувати для передачі функцій як параметрів public delegate double Real. Func (double x); public double Integrate (double a, double b, int n, Real. Func f) { double dx = (b – a) / n, res = 0. 0; for(int j = 0; j < n; j++) res += f (a + j * dx) * dx; return res; } // end of Integrate() double s = Integrate(0, 1, 1000, Math. Sin);
Ланцюжок делегатів n Дозволяє, викликавши один делегат, послідовно викликати декілька методів (з однаковою сигнатурою) public abstract class Multicast. Delegate : Delegate { public sealed override Delegate[] Get. Invocation. List(); // повертає список делегатів private Int. Ptr _invocation. Count; private object _invocation. List; … } n Multicast. Delegate може зберігати посилання не на одну функцію, а на декілька n Під час виклику делегата функції можуть виконуватися в довільному порядку n Якщо функції повертають значення, то тільки останнє значення можна буде використовувати n У випадку виникнення необробленої виключної ситуації, переривається весь ланцюжок
Клас Delegate public abstract class Delegate : ICloneable{ public static Delegate Combine (params Delegate[] delegates); public static Delegate Combine (Delegate delegate 1, Delegate delegate 2); public static Delegate Remove (Delegate source, Delegate value); public static Delegate Remove. All (Delegate source, Delegate value); public virtual Delegate[] Get. Invocation. List(); … } n Класи Delegate і Multicast. Delegate незмінювані, тому всі методи комбінації делегатів статичні і повертають новий екземпляр делегата n Combine() – об'єднує делегати або ланцюжки делегатів у новий ланцюжок делегатів n Remove() – знищує вказаний делегат з ланцюжка (перший, що зустрівся з кінця) n Remove. All() – знищує усі копії вказаного делегата із ланцюжка n Get. Invocation. List() – повертає ланцюжок делегатів у вигляді масиву одиночних делегатів
Скорочення запису створення ланцюжка делегатів n Використання операції додавання і віднімання +, -. n Використання += і -= n Приклади: n Process. Result delegate 1 = new …. , delegate 2 = new …. n Process. Result chain = delegate 1 + delegate 2; n chain += delegate 3; n Process. Result chain = (Process. Result)Delegate. Combine(delegate 1, delegate 2);
Ланцюжок делегатів n Виклик ланцюжка делегатів такий же (послідовно викликаються всі методи в цьому ланцюжку) double d = chain(5, 10); n Ітерація по ланцюжку делегатів Delegate[] delegates = chain. Get. Ivocation. List(); Process. Result pr = (Process. Result) delegates[0]; double result = pr(5, 6); foreach (Process. Result del in chain. Get. Invocation. List()) { Console. Write. Line(del(x, y)); }