Чтение онлайн

на главную - закладки

Жанры

Интернет-журнал "Домашняя лаборатория", 2007 №9
Шрифт:

У класса Delegate, помимо методов, наследуемых от класса object, есть еще несколько методов, но мы на них останавливаться не будем, они используются не столь часто.

Операции "+" и "-"

Наряду с методами, над делегатами определены и две операции: "+" и "-", которые являются более простой формой записи добавления делегатов в список вызовов и удаления из списка. Операции заменяют собой методы Combine и Remove. Выше написанные присваивания объекту dell

с помощью этих операций могут быть переписаны в виде:

del1 +=del2;

del1 — =del2;

Как видите, запись становится проще, исчезает необходимость в задании явного приведения к типу. Ограничения на del1 и del2, естественно, остаются те же, что и для методов Combine и Remove.

Пример "Комбинирование делегатов"

Рассмотрим следующую ситуацию. Пусть есть городские службы: милиция, скорая помощь, пожарные. Каждая из служб по-своему реагируют на события, происходящие в городе. Построим примитивную модель жизни города, в которой случаются события и сообщения о них посылаются службам. В последующей лекции эта модель будет развита. Сейчас она носит формальный характер, демонстрируя, главным образом, работу с делегатами, заодно поясняя ситуации, в которых разумно комбинирование делегатов.

Начнем с построения класса с именем Combination, где, следуя уже описанной технологии, введем делегатов как закрытые свойства, доступ к которым идет через процедуру-свойство get. Три делегата одного класса будут описывать действия трех городских служб. Класс будет описываться ранее введенным делегатом MesToPers, размещенным в пространстве имен проекта. Вот программный код, в котором описаны функции, задающие действия служб:

class Combination

{

private static void policeman (string mes)

{

//анализ сообщения

if(mes =="Пожар!")

Console.WriteLine(mes + " Милиция ищет виновных!");

else

Console.WriteLine(mes +" Милиция здесь!");

}

private static void ambulanceman(string mes)

{

if(mes =="Пожар!")

Console.WriteLine(mes + " Скорая спасает пострадавших!");

else

Console.WriteLine(mes + " Скорая помощь здесь!");

}

private static void fireman(string mes)

{

if(mes =="Пожар!")

Console.WriteLine(mes + " Пожарные тушат пожар!");

else

Console.WriteLine(mes + " Пожарные здесь!");

}

}

Как видите, все три функции имеют не только одинаковую сигнатуру, но и устроены одинаково. Они анализируют приходящее к ним сообщение, переданное через параметр mes, а затем, в зависимости от результата, выполняют ту или иную работу, которая в данном случае сводится к выдаче соответствующего сообщения. Сами функции закрыты, и мы сейчас организуем к ним доступ:

public static MesToPers Policeman

{

get {return (new MesToPers(policeman));}

}

public static MesToPers Fireman

{

get {return (new MesToPers(fireman));}

}

public static MesToPers Ambulanceman

(

get (return (new MesToPers(ambulanceman));}

}

Три

статических открытых свойства — Policeman, Fireman, Ambulanceman — динамически создают экземпляры класса MesToPers, связанные с соответствующими закрытыми функциями класса.

Службы у нас есть, покажем, как с ними можно работать. С этой целью добавим в класс Testing, где проводятся различные эксперименты, следующую процедуру:

public void TestSomeServices

{

MesToPers Comb;

Comb = (MesToPers)Delegate.Combine(Combination.Ambulanceman,

Combination.Policeman);

Comb = (MesToPers)Delegate.Combine(Comb,Combination.Fireman);

Comb("Пожар!");

Вначале объявляется без инициализации функциональная переменная Comb, которой в следующем операторе присваивается ссылка на экземпляр делегата, созданного методом Combine, чей список вызова содержит ссылки на экземпляры делегатов Ambulanceman и Policeman. Затем к списку вызовов экземпляра Comb присоединяется новый кандидат Fireman. При вызове делегата Comb ему передается сообщение "Пожар!". В результате вызова Comb поочередно запускаются все три экземпляра входящие в список, каждому из которых передается сообщение.

Давайте теперь начнем поочередно отключать делегатов, вызывая затем Comb с новыми сообщениями:

Comb = (MesToPers)Delegate.Remove (Comb,Combination.Policeman);

//Такое возможно: попытка отключить не существующий элемент

Comb = (MesToPers)Delegate.Remove (Comb,Combination.Policeman);

Comb ("Через 30 минут!");

Comb = (MesToPers)Delegate.Remove(Comb,Combination.Ambulanceman);

Comb("Через час! ");

Comb = (MesToPers)Delegate.Remove(Comb,Combination.Fireman);

//Comb("Через два часа!"); // Comb не определен

В этом фрагменте поочередно отключаются разные службы — милиция, скорая помощь, пожарные, и каждый раз вызывается Comb. После последнего отключения, когда список вызовов становится пустым, вызов Comb приводит к ошибке, потому оператор вызова закомментирован.

Покажем теперь, что ту же работу можно выполнить, используя не методы, а операции:

//операции + и -

Comb = Combination.Ambulanceman;

Console.WriteLine(Comb.Method.Name);

Comb+= Combination.Fireman;

Comb+= Combination.Policeman;

Соmb("День города!");

Comb — = Combination.Ambulanceman;

Comb — = Combination.Fireman;

Comb("На следующий день!");

}//TestSomeServices

Обратите внимание, здесь демонстрируется вызов свойства Method, возвращающее объект, свойство Name которого выводится на печать. Результаты, порожденные работой этой процедуры, изображены на рис. 20.6.

<
Поделиться:
Популярные книги

Вечный. Книга I

Рокотов Алексей
1. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга I

Попаданка в деле, или Ваш любимый доктор

Марей Соня
1. Попаданка в деле, или Ваш любимый доктор
Фантастика:
фэнтези
5.50
рейтинг книги
Попаданка в деле, или Ваш любимый доктор

Вперед в прошлое!

Ратманов Денис
1. Вперед в прошлое
Фантастика:
попаданцы
5.00
рейтинг книги
Вперед в прошлое!

Жена проклятого некроманта

Рахманова Диана
Фантастика:
фэнтези
6.60
рейтинг книги
Жена проклятого некроманта

Третий. Том 2

INDIGO
2. Отпуск
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Третий. Том 2

Королева Солнца. Предтечи. Повелитель зверей. Кн. 1-17

Нортон Андрэ
Королева Солнца
Фантастика:
фэнтези
6.25
рейтинг книги
Королева Солнца. Предтечи. Повелитель зверей. Кн. 1-17

Опасная любовь командора

Муратова Ульяна
1. Проклятые луной
Фантастика:
фэнтези
5.00
рейтинг книги
Опасная любовь командора

Лютая

Шёпот Светлана Богдановна
Любовные романы:
любовно-фантастические романы
6.40
рейтинг книги
Лютая

Леди для короля. Оборотная сторона короны

Воронцова Александра
3. Королевская охота
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Леди для короля. Оборотная сторона короны

Светлая тьма. Советник

Шмаков Алексей Семенович
6. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Светлая тьма. Советник

Измена дракона. Развод неизбежен

Гераскина Екатерина
Фантастика:
городское фэнтези
фэнтези
5.00
рейтинг книги
Измена дракона. Развод неизбежен

Попаданка для Дракона, или Жена любой ценой

Герр Ольга
Любовные романы:
любовно-фантастические романы
7.17
рейтинг книги
Попаданка для Дракона, или Жена любой ценой

Адвокат империи

Карелин Сергей Витальевич
1. Адвокат империи
Фантастика:
городское фэнтези
попаданцы
фэнтези
5.75
рейтинг книги
Адвокат империи

Измена. Избранная для дракона

Солт Елена
Любовные романы:
любовно-фантастические романы
3.40
рейтинг книги
Измена. Избранная для дракона