Информационный сайт

 

Реклама
bulletinsite.net -> Книги на сайте -> Программисту -> Троелсен Э. -> "С# и платформа .NET. Библиотека программиста" -> 101

С# и платформа .NET. Библиотека программиста - Троелсен Э.

Троелсен Э. С# и платформа .NET. Библиотека программиста — СПб.: Питер, 2004. — 796 c.
ISBN 5-318-00750-3
Скачать (прямая ссылка): cplatforma2004.pdf
Предыдущая << 1 .. 95 96 97 98 99 100 < 101 > 102 103 104 105 106 107 .. 320 >> Следующая

assembly CaCeiegais as "CarDelegate" 1
4
Рис. 5.4. Вложенный делегат
Члены System.MulticastDelegate
Конечно, делегат был создан как тип, производный от SysterjJult'castSelegate, не потому, что «так захотелось», а заі ем, чтобы каждый делегат С# унаследовал набор полезных членов, предназначенных для использования программистами. Наиболее интересные члены, которые иасл^ую'и-ялюбымиделепп'ам» or System.MuIt icast-Delegate, представлены в табл. 5.2.
Таблица 5.2. Некоторые унаследованные члены делегатов Член Назначение
Method Это свойство возвращает имя метода, на который указывает делегат
Target Если делегат указывает на метод — член класса, то этот член возвращает
имя этого класса. Если Target возвращает значение типа null, то делегат указывает на статический метод
Combine() Этот статический метод используется для создания делегата,
указывающего на несколько разных функций
GetlnvocationListO Возвращает массив типов Delegate, каждый из которых представляет собой запись во внутреннем списке указателей на функции делегата
Remove<) Этот статический метод удаляет делегат из списка указателей на функции
Многоадресный делегат (multicast delegate) позволяет указывать на любое количество функций. При этом внутри делегата создается внутренний список указате-лейна функции. Поскольку все делегаты С# производятся от System. MultlcastDelegate, то любой делегат С# потенциально является многоадресным. Чтобы добавить новый указатель на функцию во внутренний список делегата, используется метод
Делегаты 239
Conbine?) или перегруженный оператор сложения +, а чтобы удалить указатель ~ метод Remove(),
Применение CarDelegate
Мы только что создали делегат, а значит, создали указатель на функцию. Это значит, что теперь мы сможем создавать новые функции, которые будут принимать наш делегат в качестве параметра. Лучше всего разобрать эту ситуацию на примере.
Предположим, что у нас есть новый класс, который называется Garage (гараж). Этот класс представляет собой набор объектов класса Саг (для создания набора используется тип Arrayl. j st). При создании объекта класса Garage внутрь этого объекта помещается несколько объектов класса Саг.
Пусть наш класс Garage определяет открытый метод ProcessCa rsC), который при -нимает единственный параметр — делегат Саг.CarDelegate. В определении метод.1. ProcessCa rs () мы будем передавать все объекты Саг из набора в качестве параметра той функции, на которую указывает наш делегат.
Чтобы проиллюстрировать схему внутренней работы делегатов, мы также воспользуемся возможностями двух унаследованных от System. !-'и і ti castDel egate членов - Target и Method. Они нам будут нужны для того, чтобы определить, на какую именно функцию в настоящий момент указывает делегат.
А вот и определение класса Garage:
// В классе Garage предусмотрен метод, приникающий CarElelegate в качестве параметра public class Garage
{
Il Набор нашин в гараже
ArrayList theCars - new ArrayListt):
II Создаем объекты машин в г арапе
public GarageO
{
Il Приненяен новый вариант конструктора theCars.Add(new carC'Viper". юо. О, true, false)): theCars.Addtnew carCFred". 100. 0. false, false)); theCars.Addtnew carC'BillyBob", 100. 0. false, true)): theCars.Addtnew car("Bart". 100. 0. true, true)): theCars.Addtnew cart"Stan", 100, 0. false, true)):
}
// Этот метод принимает Car.CarDelegate в качестве параметра. Таким образом, // иожно считать, что ргос - это эквивалент указтеля на функцию public void ProcessCars(Car.CarDelegate ргос) t
Il Интересно, а куда ш передаем наш вызов?
Console.WriteLine("***** Calling: {0} *****". ргос.Method. ToStringO):
// Еще одна проверка: вызываемый метод является статическим или // обычным?
if (ргос. Target !- null)
Console.WriteLine("->Target: {0}", ргос.Target.ToStringt));
else
Console. Un teLineC ^Target is a static method"):
240 Глава 5 Дополнительные возможности классов С#
// Для чего это все затевалось: при помоги делегата вызываем метод
// и передаем єну все объекты Саг foreachCcar с in the Cars) proc(c):
}
При вызове метода ProcessCat's() необходимо передать ему в качестве параметра имя метода, который должен обработать данный вызов. Например, пусть у нас есть два статических метода - WashCarC > (помыть машину) и RotateTiresO (заменить покрышки). Вызов этих методов через Car.CarDelegate может выглядеть следующим образом:
// Гараж г-ереаает право выполнить всю работу этик статическим функциям -// наверное, у него нет хороших механиков... public class СагАрр
{ // Первый нетод. на который будет указывать делегат public static void WashCarCCar с) {
1tEc.Dir.ty)
Console.Writet1ne("Cleaning a car");
else
Console. Wrlteti ne("TMs car is already clean,.,");
)
Il Второй метод для делегата
public static void RotateTires(Car c)
{
if (c. Rotate)
Console.WritetineC'Tires have been rotated");
else
Console.ynteU net :Don4 need to be rotated..."):
)
public static Main(string[] args) {
Il Создаем объект Garage Garage g - new GarageO;
Il Ноем все грязные машины g.ProcessCarstnew Car.CarDelegate(WashCar)):
Предыдущая << 1 .. 95 96 97 98 99 100 < 101 > 102 103 104 105 106 107 .. 320 >> Следующая
Реклама
Авторские права © 2009 AdsNet. Все права защищены.
Rambler's Top100