Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Изменение аргументов






Проблема защиты аргументов распадается на две проблемы - защита входных аргументов и защита выходных аргументов. Первая из этих проблем сводится к защите входных аргументов от попыток их изменений обработчиками события. Решить эту проблему можно достаточно просто при проектировании класса, порождающего события. Если быть более точным, проблема решается при проектировании класса, задающего входные и выходные аргументы события и являющегося наследником класса EventArgs. Поля этого класса делаются закрытыми, а методы свойства, реализующие доступ к полям, позволяют клиентам класса только чтение значений, запрещая запись в поля. Тем самым, ни один из классов receiver не сможет изменить значения входных аргументов.

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

Для решения данной проблемы sender вместо посылки сообщения всем, кто его готов принять, объект получает список вызова, используя метод GetInvocationList, и поочередно вызывает обработчиков события, обрабатывая после вызова значения выходных аргументов.

Пример " Списки с событиями"

В этом примере строится класс ListWithChangedEvent, позволяющий работать со списками и являющийся потомком встроенного класса ArrayList. В класс добавляется событие Changed, сигнализирующее обо всех изменениях элементов списка. Начнем с объявления делегата:

// Объявление делегата public delegate void ChangedEventHandler(object sender, ChangedEventArgs args);

Здесь объявлен делегат ChangedEventHandler, по всем правилам хорошего стиля - его имя и его форма соответствуют всем требованиям. Второй аргумент, задающий аргументы события, принадлежит классу ChangedEventArgs, производному от встроенного класса EventArgs. Рассмотрим, как устроен этот производный класс:

/// < summary> /// Дополнительные аргументы события/// < /summary> public class ChangedEventArgs: EventArgs{ string name; //входной аргумент object item; //входной аргумент bool permit; //выходной аргумент public string Name { get { return name; } } //только чтение public object Item { get { return (item); } } //только чтение public bool Permit { get {return(permit); } set { permit = value; } //чтение и запись } public ChangedEventArgs(string name, object item) { this.name = name; this.item = item; } public ChangedEventArgs() {} }//class ChangedEventArgs

У класса три закрытых свойства, доступ к которым осуществляется через методы-свойства. Эти свойства задают дополнительные аргументы, которые передаются методам, обрабатывающим события. Два свойства - name и item - имя объекта и значение элемента списка - задают входную информацию, на основе которой обработчик события принимает решение. Третий аргумент - permit является выходным аргументом. Деление аргументов на входные и выходные выполняется на содержательном уровне и никак синтаксически не поддерживается. Разработчик класса, реализуя разные стратегии доступа к аргументам, тем самым разделяет их на входные и выходные. К входным аргументам открыт доступ только на чтение, так что ни один из обработчиков события не сможет изменить значения этих аргументов. Для выходного аргумента возможно как чтение, так и запись.

У класса два конструктора: один - без аргументов, второму передаются входные аргументы.

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

Правильно ли, что обработчик события принимает решение о допуске изменения элемента списка? Все зависит от контекста. В прошлые времена молодые могли объявить о своей помолвке, но требовалось разрешение родителей на брак. Времена изменились, теперь родительского благословения не требуется. Тем не менее, ситуации, требующие внешнего разрешения, встречаются довольно часто. У работника возникли события - получил приглашение на конференцию, появилась возможность заключения выгодного контракта. Во всех таких случаях требуется одобрение коллег и начальства. Заметьте, окончательное решение остается за объектом, пославшим сообщение.






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.