Частина 3. Делегати. Групова адресація. Створення списків викликів методів
Дана тема базується на попередній темі:
Зміст
- Питання/відповідь
- 1. Що означає термін “групова адресація методів”?
- 2. Які переваги дає використання групової адресації при роботі з делегатами?
- 3. Які операції використовуються при груповій адресації?
- 4. Приклад додавання та видалення методів списку
- 5. Що відбудеться, якщо видалити метод, якого немає в списку методів?
- 6. Як здійснюється групова адресація, якщо делегат повертає значення?
- 7. Як працює групова адресація, якщо делегат повертає тип void?
- 8. Приклад, що демонструє використання групової адресації для делегатів, які повертають значення (методи повертають значення)
- 9. Приклад, що демонструє використання групової адресації для делегатів, які повертають тип void
- Зв’язані теми
Пошук на інших ресурсах:
1. Що означає термін “групова адресація методів”?
Делегат може посилатись на групу методів, які зв’язані між собою в зв’язаний однонаправлений список (ланцюг). Групова адресація – це спосіб (можливість) створення списку методів, які викликаються автоматично при зверненні до делегату.
⇑
2. Які переваги дає використання групової адресації при роботі з делегатами?
Групова адресація дозволяє сформувати списки (ланцюги) викликів. Це є ефективним, оскільки:
- можна гнучко формувати списки методів, що повинні викликатись одним єдиним викликом делегату;
- зручно формувати списки методів, які виконують різні види роботи над деяким спільним об’єктом;
- покращується структура програмного коду;
- зручно обробляти події, які генеруються системою.
⇑
3. Які операції використовуються при груповій адресації?
Для організації групової адресації методів з допомогою делегата використовуються 4 операції:
- операції ‘+’ та ‘+=’ – додають метод до списку методів;
- операції ‘−’ та ‘−=‘ – видаляють метод зі списку методів.
⇑
4. Приклад додавання та видалення методів списку
Нехай дано методи з іменами Method1(), Method2(), Method3(). Нехай задано делегат з іменем ListM.
Нижченаведений код демонструє використання операцій ‘+’, ‘+=’, ‘–’, ‘−=’.
Щоб додати метод Method2 до делегату (списку) ListM, потрібно виконати такий код:
ListM = ListM + Method2;
Інший спосіб додавання методу
ListM += Method2;
Щоб видалити метод Method2 потрібно написати:
ListM = ListM - Method2;
або
ListM -= Method2;
⇑
5. Що відбудеться, якщо видалити метод, якого немає в списку методів?
Нічого не відбудеться. Якщо методу з іменем M немає в списку (ланцюгу) методів, тоді рядок видалення (операції ‘−’ або ‘−=’) пропускається.
⇑
6. Як здійснюється групова адресація, якщо делегат повертає значення?
Якщо в делегаті сформований список методів, які повертають деякий тип, відмінний від типу void, тоді результатом виклику буде результат повернення останнього методу в списку.
Щоб отримати результат роботи всіх методів списку, потрібно використати метод GetInvocationList(). Цей метод повертає масив усіх методів, що сформовані в делегаті у вигляді списку.
⇑
7. Як працює групова адресація, якщо делегат повертає тип void?
Якщо делегат повертає тип void, то при виклику делегата викликаються усі методи, що сформовані в список (ланцюг) з допомогою групової адресації.
Послідовність виклику методів відповідає послідовності додавання методів до списку. Перший доданий метод викликається першим, другий доданий метод викликається другим і т.д.
⇑
8. Приклад, що демонструє використання групової адресації для делегатів, які повертають значення (методи повертають значення)
Приклад, в якому делегат повертає значення. Для демонстрації вибрано методи обчислення характеристик геометричних фігур (довжина кола, площа круга, об’єм сфери).
Приклад.
Дано оголошення типу делегату CalcFigures, який повертає значення типу double:
// Оголошення типу делегату, що повертає значення delegate double CalcFigures(double r);
Дано опис статичних методів, що будуть формуватись в список:
// Оголошення статичних методів класу // довжина кола public static double Get_Lentgh(double r) { double length = 3.1415 * r * 2; return length; } // площа круга public static double Get_Area(double r) { double area = 3.1415 * r * r; return area; } // об'єм кулі public static double Get_Volume(double r) { double volume = 4.0 / 3.0 * 3.1415 * r * r * r; return volume; }
В іншому програмному коді (наприклад, обробнику події) оголошуються делегати та формується список (група) методів, на які посилається делегат:
// Оголошення делегатів CalcFigures CF; CalcFigures GetL = Get_Lentgh; CalcFigures GetA = Get_Area; CalcFigures GetV = Get_Volume; ... // організувати групову адресацію CF = GetL; // CF посилається на метод Get_Length: CF->GetL // додати до списку CF метод Get_Volume CF = CF + GetV; // або CF += GetV; // додати до списку CF метод Get_Area CF += GetA; // CF => Get_Length->Get_Volume->Get_Area result = CF(3.0); // result = 28.2735 - викликається метод Get_Area // видалити зі списку CF метод Get_Area CF -= GetA; // CF => Get_Length->Get_Volume result = CF(3.0); // result = 113.094 - викликаєтья метод Get_Volume // додати знову метод Get_Length CF += GetL; // CF => Get_Length->Get_Volume->Get_Length result = CF(3.0); // result = 18.849 - викликається Get_Length // видалити метод Get_Length CF -= GetL; // CF => Get_Length->Get_Volume result = CF(3.0); // result = 113.094 - викликається Get_Volume // видалити знову Get_Length CF -= GetL; // CF => Get_Volume - у списку залишився один метод Get_Volume result = CF(3.0); // result = 113.094 // видалити останній метод Get_Volume CF -= GetV; // CF => список пустий
⇑
9. Приклад, що демонструє використання групової адресації для делегатів, які повертають тип void
У даному прикладі продемонстровано групову адресацію для методів, що здійснюють деяку операцію над дійсним числом x, а саме:
- множення числа x на 2 (метод Mult2());
- множення числа x на 3 (метод Mult3());
- піднесення числа x до квадрату (метод Sqr()).
Оголошення типу делегату:
// Оголошення типу делегату delegate void CalcNumber(ref double x);
Оголошення методів
// методи, що обробляють дійсне число // множення числа на 2 public static void Mult2(ref double x) { x = x * 2; } // множення числа на 3 public static void Mult3(ref double x) { x = x * 3; } // піднесення числа до квадрату public static void Sqr(ref double x) { x = x * x; }
Демонстрація групової адресації для делегату що повертає тип void, з іншого програмного коду (наприклад, обробника події):
// Оголошення делегату CalcNumber CN; // додаткова змінна double x; // Створення списку методів - 1 CN = Mult2; // CN => Mult2 CN += Mult2; // CN => Mult2 -> Mult2 CN += Sqr; // CN => Mult2 -> Mult2 -> Sqr CN = CN + Mult3; // CN => Mult2 -> Mult2 -> Sqr -> Mult3 x = 2.0; CN(ref x); // x = 192 = ((2.0 * 2 * 2)^2 ) * 3 // Видалення усіх методів CN -= Mult3; CN -= Mult2; CN -= Mult2; CN -= Sqr; // CN => список пустий // Створення списку методів - 2 CN = Sqr; // CN => Sqr CN += Sqr; // CN => Sqr -> Sqr CN += Mult3; // CN => Sqr -> Sqr -> Mult3 CN += Mult2; // CN => Sqr -> Sqr -> Mult3 -> Mult2 x = 2.0; CN(ref x); // x = 96 = (2.0 ^ 2 ^ 2) * 3 * 2
⇑
Зв’язані теми
- Поняття делегату. Оголошення типу делегату. Використання делегатів у програмі. Групове перетворення методів
- Використання делегатів, які посилаються на методи екземпляру класу. Приклад
- Анонімні функції. Анонімні методи. Повернення значення. Передача параметрів
- Приклад розв’язку задачі, що обчислює характеристики геометричних фігур з використанням делегатів
- Приклади передачі масивів, структур, класів анонімному методу
- Події і делегати. Поняття події. Взаємодія між подіями. Приклади використання подій