Программирование >>  Обработка исключительных ситуаций 

1 ... 74 75 76 [ 77 ] 78 79 80 ... 142


Листинг 10.7. Оповещение наблюдателей с помощью событий

using System;

namespace ConsoleApplicationl {

public delegate void DelO;

class Subj

public event Del Oops;

public void CryOopsO

Console.WriteLineC OOPS! ); if ( Oops != null ) OopsO:

объявление делегата класс-источник объявление события метод, инициирующий событие

class ObsA класс-наблюдатель

public void DoO; реакция на событие источника

Console.WriteLineC Вижу, что OOPS! );

class ObsB

public static void SeeO

класс-наблюдатель реакция на событие источника

Console.WriteLineC Я тоже вижу, что OOPS! )

class Classl

static void MainO

{ Subj s = new Subj();

ObsA ol = new ObsAC):

ObsA o2 = new ObsAC);

s.Oops += new DelC ol.Do );

s.Oops += new DelC o2.Do );

s.Oops += new DelC ObsB.See );

s. CryOopsO;

объект класса-источника

объекты класса-наблюдателя

добавление обработчиков к событию

инициирование события



Внешний код может работать с событиями единственным образом: добавлять обработчики в список или удалять их, поскольку вне класса могут использоваться только операции += и -=. Тип результата этих операций - void, в отличие от операций сложного присваивания для арифметических типов. Иного способа доступа к списку обработчиков нет.

Внутри класса, в котором описано событие, с ним можно обращаться, как с обгч-ным полем, имеющим тип делегата: использовать операции отношения, присваивания и т. д. Значение события по умолчанию - null. Например, в методе CryOops выполняется проверка на nul 1 для того, чтобы избежать генерации исключения System.Nul1ReferenceException.

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

имя делегата заканчивается суффиксом EventHandler;

делегат получает два параметра:

О первый параметр задает источник события и имеет тип object; О второй параметр задает аргументы события и имеет тип EventArgs или производный от него.

Если обработчикам события требуется специфическая информация о событии, то для этого создают класс, производный от стандартного класса EventArgs, и добавляют в него необходимую информацию. Если делегат не использует такую информацию, можно не описывать делегата и собственный тип аргументов, а обойтись стандартным классом делегата System.EventHandler.

Имя обработчика события принято составлять из префикса On и имени события. В листинге 10.8 приведен пример из листинга 10.7, оформленный в соответствии со стандартными соглашениями .NET. Найдите восемь отличий!

Листинг 10.8. Использование стандартного делегата EventHandler

using System;

namespace ConsoleApplicationi

class Subj {

public event EventHandler Oops; public void CryOops()

Console.WriteLineC OOPS! );

if ( Oops != null ) OopsC this, null );

class ObsA



s.CryOopsO:

Те, кто работает с С# версии 2.0, могут упростить эту программу, используя новую возможность неявного создания делегатов при регистрации обработчиков событий. Соответствующий вариант приведен в листинге 10.9. В демонстрационных целях в код добавлен новый анонимный обработчик - еще один механизм, появившийся в новой версии языка.

Листинг 10.9. Использование делегатов и анонимных методов (версия 2.0)

using System;

namespace ConsoleApplicationl

class Subj

public event EventHandler Oops; public void CryOopsO

Console.WriteLineC OOPS! )

Листинг 10.8 (продолжение)

public void OnOopsC object sender. EventArgs e ) {

Console.WriteLineC Вижу, что OOPS! );

class ObsB

public static void OnOopsC object sender, EventArgs e )

Console.WriteLineC Я тоже вижу, что OOPS! ):

class Classl

{ static void MainO

Subj s = new SubjC);

ObsA ol = new ObsAC);

ObsA o2 = new ObsAC);

s.Oops += new EventHandlerC ol.OnOops ): s.Oops += new EventHandlerC o2.0nOops ): s.Oops +- new EventHandlerC ObsB.OnOops );



1 ... 74 75 76 [ 77 ] 78 79 80 ... 142

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика