logo
C#, 320 стр

Переопределение значений аргументов события

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

Приведенный выше пример "Работа со списками" демонстрирует не самый лучший способ определения аргументов, провоцирующий классы Receiver на некорректное обращение с аргументами. Напомню, в классе ChangedEventArgs, определяющем аргументы события, оба свойства item и permit являются закрытыми. Но определены процедуры - свойства Item и Permit, реализующие полный доступ к свойствам, поскольку определены обе процедуры get и set. Это несколько облегчило задачу, поскольку позволило изменять значение входного аргумента item перед зажиганием события для передачи его обработчику. Но входной аргумент оказался не защищенным, и обработчик события может не только использовать это значение для анализа, но и изменить его в качестве побочного эффекта своей работы. В этом случае другой обработчик будет работать уже с некорректным значением. Что еще хуже - это измененное значение может использовать и класс, в процессе своей дальнейшей работы. Поэтому входные аргументы события должны быть закрытыми для обработчиков событий. Это нетрудно сделать, и я приведу необходимые уточнения.

}

}

Таким образом, обработчикам можно запретить изменение входных аргументов события. Но есть еще выходные аргументы события, значения которых определяются в обработчике; в нашем примере это аргумент Permit.

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

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

Итак, если событие имеет аргументы, то все входные аргументы должны быть закрыты для обработчиков события. Если обработчиков несколько, то лучше или не использовать выходных аргументов, или аккуратно запрограммировать логику обработчиков, которая учитывает решения, полученные коллегами - ранее отработавшими обработчиками события.