Часть 3. Делегаты. Групповая адресация. Создание цепочек вызовов методов
Данная тема базируется на предыдущей теме:
Содержание
- Вопрос/ответ
- 1. Что означает термин «групповая адресация методов»?
- 2. Какие преимущества дает использование групповой адресации при работе с делегатами?
- 3. Какие операции используются при групповой адресации?
- 4. Пример добавления и удаления методов в списке
- 5. Что произойдет, если попробовать удалить метод, которого нет в списке методов?
- 6. Как работает групповая адресация, если делегат возвращает значение?
- 7. Как работает групповая адресация, если делегат возвращает тип void?
- 8. Пример, который демонстрирует использование групповой адресации для делегатов, которые возвращают значение (методы возвращают значение)
- 9. Пример, демонстрирующий использование групповой адресации для делегатов, возвращающих тип void
- Связанные темы
Поиск на других ресурсах:
1. Что означает термин «групповая адресация методов»?
Делегат может ссылаться на группу методов, которые связаны между собой в цепочку. Групповая адресация – это способ (возможность) создания списка методов, которые вызываются автоматически при обращении к делегату.
⇑
2. Какие преимущества дает использование групповой адресации при работе с делегатами?
Групповая адресация позволяет сформировать списки (цепочки) вызовов. Это есть эффективным, поскольку:
- можно гибко формировать списки методов, которые должны вызываться по одному вызову делегата;
- удобно формировать списки методов, которые выполняют разные виды работ над некоторым общим объектом;
- улучшается структура программного кода;
- удобно обрабатывать события, которые генерируются системой.
⇑
3. Какие операции используются при групповой адресации?
Для организации групповой адресации методов с помощью делегата используются 4 операции:
- операции ‘+’ и ‘+=’ – добавляют метод к списку методов;
- операции ‘−’ и ‘−=’ – удаляют метод из списка методов.
⇑
4. Пример добавления и удаления методов в списке
Пусть даны методы с именами Method1(), Method2(), Method3(). Пусть задан делегат с именем List.
Нижеследующий код демонстрирует использование операций ‘+’, ‘+=’, ‘−’, ‘−=’.
Чтобы добавить метод Method2 к делегату (списку) List, нужно выполнить такой код:
List = List + Method2;
Другой способ добавления метода
ListM += Method2;
Чтобы удалить метод Method2 нужно написать:
List = List - 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->Get // добавить к списку 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);
Объявление методов
// методы, что оперируют вещественным числом x // умножение числа на 2 public static void Mult2(ref double x) { x = x * 2; } // умножение числа на 3 public static void Mult3(ref double x) { x = x * 3; } // квадрат числа x 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
⇑
Связанные темы
- Понятие делегата. Объявление типа делегата. Использование делегата в программе. Групповое преобразование методов
- Использование делегатов, которые ссылаются на методы экземпляра класса
- Пример решения задачи, вычисляющей характеристики геометрических фигур с использованием делегатов
- Анонимные функции. Анонимные методы. Возврат значения. Передача параметров
- Примеры передачи массивов, структур, классов анонимному методу
- События и делегаты. Понятие события. Взаимодействие между событиями. Примеры использования событий