Делегаты в качестве параметров
Делегаты в качестве параметров
Теперь, когда у нас есть новый тип делегата, который указывает на методы, получающие Car в виде параметра и не возвращающие ничего, мы можем создавать функции, которые принимают этот делегат в виде параметра. Для примера предположим, что у нас есть новый класс, которому назначено имя Garage (гараж). Этот тип поддерживает коллекцию типов Car, содержащихся в System.Collections. ArrayList. При создании ArrayList наполняется типами Car.
// Класс Garage хранит список типов Car.
using System.Collections;
…
public class Garage {
// Создание списка всех машин в гараже.
ArrayList theCars = new ArrayList();
// Создание машин в гараже.
public Garage() {
// Напомним, что конструктор был обновлен,
// и теперь можно установить значения isDirty и shouldRotate.
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));
}
}
Класс Garage будет определять общедоступный метод ProcessCars(), который в качестве единственного аргумента получит новый тип делегата (Car.CarDelegate). В ProcessCars() каждый объект Car из коллекции будет передаваться в виде параметра "той функции, на которую указывает" делегат. При этом ProcessCars() использует члены Target и Method из System.MulticastDelegate, чтобы определить, на какую из функций делегат указывает в настоящий момент.
// Класс Garage имеет метод, использующий CarDelegate.
using System.Collections;
…
public class Garage {
…
// Этот метод получает Car.CarDelegate в виде параметра.
public void ProcessCars(Car.CarDelegate proc) {
// Куда направить вызов?
Console.WriteLine("***** Вызывается: {0} *****", proc.Method);
// Вызывается метод экземпляра или статический метод?
if (proc.Target != null) Console.WriteLine("-›Цель: {0} ", proc.Target);
else Console.WriteLine("-›Целевым является статический метод");
// Вызов "указанного" метода всех машин по очереди.
foreach (Car с in theCars) {
Console.WriteLine(" -› Обработка Car");
proc(c);
}
}
}
Как и в случае любого делегата, при вызове ProcessCars() мы должны указать имя метода, который обработает запрос. Напомним, что такой метод может быть или статическим, или методом экземпляра. Для примера предположим, что в качестве такого метода будут использоваться члены экземпляра нового класса ServiceDepartment (отдел технического обслуживании), которым назначены имела WashCar() и RotateTires(). Обратите внимание на то, что эти два метода используют новые свойства Rotate и Dirty типа Car.
// Этот класс определяет методы, которые будут вызываться
// типом Car.CarDelegate.
public class ServiceDepartment {
public void WashCar(Car c) {
if (c.Dirty) Console.WriteLine("Моем машину");
else Console.WriteLine("Эта машина уже помыта…");
}
public void RotateTires(Car с) {
if (c.Rotate) Console.WriteLine("Меняем шины");
else Console.WriteLine("Менять шины не требуется…");
}
}
Теперь проиллюстрируем взаимодействие между новыми типами Car, CarDelegate, Garage и ServiceDepartment, рассмотрев их использование в следующем фрагменте программного кода.
// Garage направляет все заказы в ServiceDepartment
// (найти хорошего механика всегда проблема…)
public class Program {
static void Main(string[] args) {
// Создание гаража.
Garage g = new Garage();
// Создание отделения обслуживания,
ServiceDepartment sd = new ServiceDepartment();
// Garage моет машины и меняет шины,
// делегируя соответствующие полномочия ServiceDepartment.
g.ProcessCars(new Car.CarDelegate(sd.WashCar));
g.ProcessCars(new Car.CarDelegate(sd.RotateTires));
Console.ReadLine();
}
}
На рис. 8.6 показан соответствующий вывод.

Рис. 8.6. Перекладывание ответственности
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
В качестве послесловия
В качестве послесловия Целью данной книги является показать важность (иногда по-настоящему критическую) клиентской оптимизации и осветить ключевые моменты и проблемные места. Очень хочется верить, что после прочтения книги у читателя сложилось целостное представление
22.4. Запуск в качестве демона
22.4. Запуск в качестве демона При разработке программ, создаваемых для работы в качестве системных демонов, нужно очень внимательно проводить их становление как демонов для правильного определения всех деталей. Ниже приведен перечень тех обстоятельств, на которые
3.8. Фреймы в качестве парадигм
3.8. Фреймы в качестве парадигм «До тех пор, пока не была создана эта парадигма схоластов (средневековая теория „первого толчка“), маятники как таковые не были известны людям, а ученые видели в них только качающиеся камни. Существование маятников было открыто благодаря
16.8 В качестве заключения
16.8 В качестве заключения В этой главе я постарался подробно рассказать об основных особенностях в работе с файлами в Ubuntu. Надеюсь, вы смогли разобраться что к чему и уловить основные моменты. Напоследок хочется заметить, что Ubuntu без какого-либо дополнительного
8.2. Сопротивление в качестве параметра
8.2. Сопротивление в качестве параметра При изучении урока 5 вам пришлось изрядно потрудиться, чтобы, «вручную» изменяя значение R в RC-фильтре нижних частот, получить диаграмму, изображенную на рис. 5.18. С помощью параметрического анализа вы сможете сделать это гораздо
8.5. Коэффициенты в качестве глобальных параметров
8.5. Коэффициенты в качестве глобальных параметров До сих пор вы называли глобальными параметрами только значения компонентов, то есть сопротивление резисторов, индуктивность катушек и емкость конденсаторов. Однако за понятием «глобальный» кроется гораздо больше. Один
Массивы в качестве параметров (и возвращаемых значений)
Массивы в качестве параметров (и возвращаемых значений) После создания массива вы можете передавать его, как параметр, или получать его в виде возвращаемого значения. Например, следующий метод PrintArray() получает входной массив строк и выводит каждый элемент на консоль, а
Интерфейсы в качестве параметров
Интерфейсы в качестве параметров Поскольку интерфейсы являются полноценными типами .NET, вы можете конструировать методы, которые будут использовать интерфейсы, как параметры. Для примера предположим, что мы определили другой интерфейс с именем IDraw3D.// Моделируем
ГЛАВА 8. Интерфейсы обратного вызова, делегаты и события
ГЛАВА 8. Интерфейсы обратного вызова, делегаты и события До этого момента в нашей книге в каждом примере приложении программный код Main() тем или иным способом направлял запросы соответствующим объектам. Но мы пока что не рассматривали возможность обратного обращения
Структуры в качестве аргументов функции
Структуры в качестве аргументов функции В не расширенном языке Си можно передавать функции адрес структуры. Например, если montana является структурной переменной структурного типа player, мы можем обратиться к функции следующим образом: stats(&montana);Функция stats( ) будет иметь
7.3.4. Абстрактные контейнерные типы в качестве параметров
7.3.4. Абстрактные контейнерные типы в качестве параметров Абстрактные контейнерные типы, представленные в главе 6, также используются для объявления параметров функции. Например, можно определить putValues() как имеющую параметр типа vectorint вместо встроенного типа
Выражения в качестве операндов
Выражения в качестве операндов Операндом при увеличении или уменьшении значения TIMESTAMP, TIME, DATE или DATE в диалекте 1 может быть константа или выражение. Выражение может быть особенно полезным в ваших приложениях, когда вам надо увеличить или уменьшить значение в секундах,
Обобщенные подпрограммы в качестве параметров
Обобщенные подпрограммы в качестве параметров Обобщенная подпрограмма может выступать в качестве формального параметра другой обобщенной подпрограммы.Например, в классе System.Array имеется несколько статических обобщенных методов с обобщенными подпрограммами в качестве
Глава 5 О качестве снимков
Глава 5 О качестве снимков Пожалуй, разговор о качестве снимков можно считать краеугольным камнем темы продажи своих фотографий на микростоковых сайтах. Очень часто, когда люди, в целом далекие от искусства фотографии, слышат о том, что кто-то продает свои фотоснимки и