|
Программирование >> Обработка исключительных ситуаций
Листинг 10.1 (продолжение) if ( s[i] else if ( s[i] else о 11 s[i] - 0) temp += O; I ) temp += Г ; temp += s[ij; temp; public static void Hack ( ref string s ) метод 2 string temp for ( int i = 0; i < s.Length; ++i ) if ( i / 2 * 2 == i ) temp += char.ToUpper( s[i] ); else temp += s[i]; s = temp; static void MainO string s Del d; cool hackers ; экземпляр делегата for ( int i = 0; i < 2; ++i ) new Del( COOl ); инициализация методом 1 if ( i 1 ) d new Del(Hack); инициализация методом 2 d( ref s ); использование делегата для вызова методов Console.WriteLine( s ); Результат работы программы: cOOl hackers COOl hAcKeRs Использование делегата имеет тот же синтаксис, что и вызов метода. Если делегат хранит ссылки на несколько методов, они вызываются последовательно в том рядке, в котором были добавлены в делегат. Добавление метода в список выполняется либо с помощью метода Combine, унаследованного от класса System.Delegate, либо, что удобнее, с помощью перегруженной операции сложения. Вот как выглядит измененный метод Main из предыдущего листинга, в котором одним вызовом делегата выполняется преобразование исходной строки сразу двумя методами: Паттерн наблюдатель Рассмотрим применение делегатов для обеспечения связи между объектами по типу источник - наблюдатель . В результате разбиения системы на множество совместно работающих классов появляется необходимость поддерживать согласованное состояние взаимосвязанных объектов. При этом желательно избежать жесткой связанности классов, так как это часто негативно сказывается на возможности многократного использования кода. Для обеспечения гибкой, динамической связи между объектами во время в1пол-нения программы применяется следующая стратегия. Объект, называемый источником, при изменении своего состояния, которое может представлять интерес для других объектов, посылает им уведомления. Эти объекты называются наблюдателями. Получив уведомление, наблюдатель опрашивает источник, чтобы синхронизировать с ним свое состояние. Примером такой стратегии может служить связь объекта с различными его представлениями, например, связь электронной таблицы с созданными на ее основе диаграммами. static void MainO string s = cool hackers ; Del d = ( C001 ) ; d += Del( ); добавление в делегат d( ref s ) ; Console.WriteLineC s ); результат: C01 hAcKeRs При вызове последовательности методов с помощью делегата необходимо учи-т1вать следующее: сигнатура методов должна в точности соответствовать делегату; метод1 могут быть как статическими, так и обычными методами класса; каждому методу в списке передается один и тот же набор параметров; если параметр передается по ссылке, изменения параметра в одном методе отразятся на его значении при вызове следующего метода; если параметр передается с ключевым словом out или метод возвращает значение, результатом выполнения делегата является значение, сформированное последним из методов списка (в связи с этим рекомендуется формировать списки только из делегатов, имеющих возвращаемое значение типа voi d); если в процессе работы метода возникло исключение, не обработанное в том же методе, последующие методы в списке не выполняются, а происходит поиск обработчиков в объемлющих делегат блоках; попытка вызвать делегат, в списке которого нет ни одного метода, вызывает генерацию исключения System. Null Ref enceExcepti on. Программисты часто используют одну и ту же схему организации и взаимодействия объектов в разных контекстах. За такими схемами закрепилось название паттерны, или шаблоны проектирования. Описанная стратегия известна под названием паттерн наблюдатель . Наблюдатель (observer) определяет между объектами зависимость типа один ко многим , так что при изменении состоянии одного объекта все зависящие от него объекты получают извещение и автоматически обновляются. Рассмотрим пример (листинг 10.2), в котором демонстрируется схема оповещения источником трех наблюдателей. Гипотетическое изменение состояния объекта моделируется сообщением OOPS! . Один из методов в демонстрационных целях сделан статическим. Листинг 10.2. Оповещение наблюдателей с помощью делегата using System; namespace ConsoleApplicationi { public delegate void Del( object о ); class Subj Del dels: public void Register( Del d ) dels += d: объявление делегата класс-источник объявление экземпляра делегата регистрация делегата public void OOPS О Console.WriteLineC OOPS! ): if ( dels != null ) dels( this ); что-то произошло оповещение наблюдателей class Ob класс-наблюдатель public void Do( object о ) реакция на событие источника Console.WriteLineC Вижу, что OOPS! ): class ObsB класс-наблюдатель public static void SeeC object о ) реакция на событие источника Console.WriteLineC Я тоже вижу, что OOPS! ):
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |