Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Otvety_1-33.docx
Скачиваний:
0
Добавлен:
18.09.2019
Размер:
509.29 Кб
Скачать

Глава 15. Делегаты, события и лямбда-выражения 463

static void ReplaceSpaces(ref string s) {

Console.WriteLine("Замена пробелов дефисами.");

s = s.Replace (' ', '-');

}

// Удалить пробелы.

static void RemoveSpaces(ref string s) {

string temp = "";

int i;

Console.WriteLine("Удаление пробелов.");

for(i=0; i < s.Length; i++)

if (s[i] != ' ') temp += s[i];

s = temp;

}

// Обратить строку.

static void Reverse(ref string s) {

string temp = "";

int i, j;

Console.WriteLine("Обращение строки.");

for(j=0, i=s .Length-l; i >= 0; i—, j++)

temp += s[i];

s = temp;

}

static void Main() {

// Сконструировать делегаты.

StrMod strOp;

StrMod replaceSp = ReplaceSpaces;

StrMod removeSp = RemoveSpaces; *

StrMod reverseStr = Reverse;

string str = "Это простой тест.";

// Организовать групповую адресацию.

strOp = replaceSp;

strOp += reverseStr;

// Обратиться к делегату с групповой адресацией.

strOp(ref str) ;

Console.WriteLine("Результирующая строка: " + str);

Console.WriteLine();

// Удалить метод замены пробелов и добавить

// метод удаления пробелов.

strOp -= replaceSp;

strOp += removeSp;

str = "Это простой тест."; // восстановить исходную строку

// Обратиться к делегату с групповой адресацией.

strOp(ref str) ;

Console.WriteLine("Результирующая строка: " + str) ;

Console.WriteLine ();

}

}

Выполнение этого кода приводит к следующему результату:

Замена пробелов дефисами.

Обращение строки.

Результирующая строка: .тсет-йотсорп-отЭ

Обращение строки.

Удаление пробелов.

Результирующая строка: .тсетйотсорпотЭ

В методе Main () из рассматриваемого здесь примера кода создаются четыре экземпляра делегата. Первый из них, strOp, является пустым, а три остальных ссылаются на конкретные м'етоды видоизменения строки. Затем организуется групповая адресация для вызова методов RemoveSpaces () и Reverse (). Это делается в приведенных ниже строках кода.

strOp = replaceSp;

strOp += reverseStr

Сначала делегату strOp присваивается ссылка replaceSp, а затем с помощью оператора += добавляется ссылка reverseStr. При обращении к делегату strOp вызываются оба метода, заменяя пробелы дефисами и обращая строку, как и показывает приведенный выше результат.

Далее ссылка replaceSp удаляется из цепочки вызовов в следующей строке кода:

strOp -= replaceSp;

и добавляется ссылка removeSp в строке кода

strOp += removeSp;

После этого вновь происходите обращение к делегату strOp. На этот раз обращается строка с удаленными пробелами.

Цепочки вызовов являются весьма эффективным механизмом, поскольку они позволяют определить ряд методов, выполняемых единым блоком. Благодаря этому улучшается структура некоторых видов кода. Кроме того, цепочки вызовов имеют особое значение для событий, как станет ясно позже.

____________________________________________________________________________________________________________

30. Події.

События позволяют классу или объекту уведомлять другие классы или объекты о возникновении каких-либо итуаций. Класс, отправляющий (или вызывающий) событие, называется издателем, а классы, принимающие (или обрабатывающие) событие, называются подписчиками.

В C# в стандартном приложении Windows Forms или веб-приложении пользователь подписывается на события, вызываемые элементами управления, такими как кнопки и поля со списками. Для просмотра событий, публикуемых элементом управления, и выбора некоторых из них для обработки можно воспользоваться средой IDE Visual C#.IDE автоматически добавит пустой метод обработчика событий и код, необходимый для подписки на событие. Дополнительные сведения см. в разделе Практическое руководство. Подписка и отмена подписки на события (Руководство по программированию в C#). События имеют следующие свойства.

  • Издатель определяет момент вызова события, подписчики определяют предпринятое ответное действие.

  • У события может быть несколько подписчиков. Подписчик может обрабатывать несколько событий от нескольких издателей.

  • События, не имеющие подписчиков, никогда не возникают.

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

  • Если событие имеет несколько подписчиков, то при его возникновении происходит синхронный вызов обработчиков событий. Сведения об асинхронном вызове событий см. в разделе Асинхронный вызов синхронных методов.

  • В библиотеке классов .NET Framework в основе событий лежит делегат EventHandler и базовый класс EventArgs.

  • / Введем специальный делегат.

  • delegate void ClickHandler();

  • class Button

  • {

  • // Это общедоступное поле-делегат, к которому каждый

  • // может присоединить собственный метод.

  • public ClickHandler Click;

  • // Несколько идеализированная функция обработки

  • // сообщений, приходящих на кнопку.

  • void OnMsg(...)

  • {

  • // Предположим

  • switch(msg)

  • {

  • // Вот мы как бы засекли нажатие на кнопку.

  • case WM_LBUTTONDOWN:

  • // Вызовем функции, связанные с нашим делегатом,

  • // предварительно проверив, а зарегистрирована

  • // ли хотя бы одна функция в поле-делегате.

  • if (Click != null)

  • Click();

  • }

  • };

___________________________________________________________________________________________________________

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]