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

Вопрос 17 Групповые делегаты. Область применения. Особенности синтаксиса.

Каждый из приведённых до этого момента делегат инкапсулировал только один метод. Однако, судействует еще один вид делегатов, которые способны инкапсулировать более одного метода, такие делегаты называются групповыми. Отличительной особенностью таких делегатов является то, что у них тип возвращаемого значения должен быть void. Одна из самых интересных возможностей делегата — поддержка многоадресатной передачи (multicasting). Многоадресатная передача — это способность создавать список вызовов (или цепочку вызовов) методов, которые должны автоматически вызываться при вызове делегата. Для создания подобной цепочки достаточно создать экземпляр делегата, а затем для добавления методов в эту цепочку использовать оператор "+=". Для удаления метода из цепочки используется оператор " - = " . Делегат с многоадресатной передачей имеет одно ограничение: он должен возвращать тип void т.е. быть групповым делегатом.

Реализуем программу приведенную в предыдущем параграфе с помощью групповых делегатов. Единственное отличие – наличие метода замены «1» на «_».

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace delegate_string

{

class Program

{

/// <summary>

/// Делегат для работы со строками

/// </summary>

delegate void StrHandler(ref string str);

/// <summary>

/// Метод заменяет "а" в строке подчеркиваниями

/// </summary>

static void replace_a(ref string s)

{

Console.WriteLine("Замена 1 подчеркиваниями!");

s=s.Replace('1', '_');

}

/// <summary>

/// Метод удаляет пробелы

/// </summary>

static void deliteSpaces(ref string s)

{

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

string _tempString="";

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

{

if (s[i] != ' ')

{

_tempString += s[i];

}

}

s = _tempString;

}

/// <summary>

/// Метод возвращает строку в обратном порядке

/// </summary>

static void ReverseString(ref string s)

{

Console.WriteLine("Реверсирование строки!");

string _tempString="";

for (int j = 0, i = s.Length - 1; i >= 0; i--, j++)

{

_tempString+=s[i];

}

s = _tempString;

}

static void Main(string[] args)

{

string new_sting = "1Это 1новая 1строка!";

StrHandler myStrHandlerReplace_a = new StrHandler(replace_a);

StrHandler myStrHandlerDeliteSpace = new StrHandler(deliteSpaces);

StrHandler myStrHandlerReverseString = new StrHandler(ReverseString);

StrHandler myHandler;

myHandler = myStrHandlerReplace_a;

myHandler += myStrHandlerDeliteSpace;

myHandler += myStrHandlerReverseString;

myHandler(ref new_sting);

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

// new_sting.Replace('1', '_');

Console.WriteLine(new_sting);

Console.ReadLine();

}

}

}

В методе Main() создаются четыре экземпляра делегата. Первый, myHandler, имеет null-значение. Три других ссылаются на методы модификации строк. Затем организуется делегат для многоадресатной передачи, который вызывает методы replace_a, deliteSpaces, ReverseString. Это достигается благодаря следующим строкам программы:

StrHandler myStrHandlerReplace_a = new StrHandler(replace_a);

StrHandler myStrHandlerDeliteSpace = new StrHandler(deliteSpaces);

StrHandler myStrHandlerReverseString = new StrHandler(ReverseString);

Сначала делегату myHandler присваивается ссылка myStrHandlerReplace_a, затем, с помощью оператора "+=", в цепочку вызовов добавляется ссылка myStrHandlerDeliteSpace, а затем myStrHandlerReverseString:

StrHandler myHandler;

myHandler = myStrHandlerReplace_a;

myHandler += myStrHandlerDeliteSpace;

myHandler += myStrHandlerReverseString;

Таким образом сначала в введенной строке «1» заменяется на нижнее подчеркивание, далее удаляются пробелы и последний этап – реверсирование строки.

Протестируем программу. На экране должно появится окно со следующим содержанием см. рисунок №1 .

Цепочки вызовов, организованные с помощью делегата, — мощный механизм, который позволяет определять набор методов, выполняемых "единым блоком". Цепочки делегатов имеют особое значение для событий.

Групповые делегаты часто используются при обработке событий. Объекты источников событий отправляют уведомления объектам получателей, зарегистрированным для получения данного события. Чтобы зарегистрироваться для получения события, объект получателя создает метод, предназначенный для обработки этого события, затем создает делегат для этого метода и передает его в источник события. Когда происходит событие, источник вызывает делегат. После этого делегат вызывает в объекте получателя метод обработки события, предоставив ему данные события. Тип делегата для данного события задается источником события.