Обоснование класса EventArgs
Я изучаю события на С# и понимаю, что класс EventArgs
содержит данные о событии. Но мне трудно понять, почему EventArgs
необходимо.
Например, в этот пример MSDN не мог класс WakeMeUp
прочитать все необходимые данные (snoozePressed
, nrings
) из полей AlarmClock
? Если он может их установить, почему он не может их получить?
Ответы
Ответ 1
Углы с классом EventArgs (как я вижу) в основном эти два:
- Вы можете добавлять участников в класс EventArgs, изменяя подпись события
- Отключить информацию, переданную обработчику событий из экземпляра объекта
Возможно, даже информация, содержащаяся в EventArgs, не отображается объектом, воссоздающим событие.
Конечно, в некоторых случаях это может показаться излишним, но я думаю, что сила одинаковости здесь хорошая; если вы знаете, как работает одно событие, вы знаете, как работают другие события.
Ответ 2
Класс EventArgs
необходим, потому что если вы хотите продлить свое событие, чтобы предоставить больше информации в будущем, у вас возникли проблемы с переносимостью для всех клиентов, использующих оригинальную сигнатуру метода исходного события.
Например,
public void IHandleEventVersion1(string p1, int p2)
{
....
}
Теперь вы хотите предоставить дополнительную информацию в событии EventVersion1
выше (вы хотите включить char
). Затем вам придется заставить клиента переписать обработку своих событий так, чтобы они соответствовали вашим новым требованиям:
public void IHandleEventVersion1(string p1, int p2, char p2)
{
...
}
Посмотрите, как это может быть неудобно при попытке предоставить дополнительную информацию?
Таким образом, класс EventArgs
предоставляет общий шаблон проектирования для программирования, позволяя вам и мне быстро расширять данные, которые мы хотим предоставить для события.
Общая схема кодирования создающей события структуры такова:
Основная стратегия обработки событий
- Определите
event
, который пользователи вашего класса могут подписаться на
- Определите подпись
delegate
, которую объявляет событие (да, вы также можете использовать стандартную версию .NET 2.0 EventHandler
, а именно EventHandler<TEventArgs>
)
- Предоставить метод
protected
virtual
для переопределения наследников в ответ на событие, возникающее в вашем базовом классе
-
В базовом классе, объявляющем ваше событие, укажите базовую реализацию метода protected
, в котором вы действительно поднимаете событие.
public class MyClass
{
public event EventHandler /* (point 2) */ MyEvent; /* (point 1) */
// (point 3 + 4)
protected virtual void OnMyEvent()
{
EventHandler temp = MyEvent;
if (temp != null)
temp(this, EventArgs.Empty);
}
public void SomeMethodThatWillRaiseTheEvent()
{
....
OnMyEvent();
}
}
Ответ 3
EventArgs полезен для:
- показывает состояние в момент времени, в котором произошло событие
- повышение производительности вашего кода обработки событий путем предоставления информации о событии без необходимости запрашивать "стороннюю сторону"
- содержащий данные, которые не отображаются объектом, восходящим к событию
Чтобы развернуть первую точку.... между вашим обработчиком событий и вы считываете состояние из объекта, который поднял событие, могли произойти другие вещи, которые полностью изменили состояние на что-то другое. В этом случае вы будете реагировать, например, на событие AlarmHasGoneOff на AlarmClock, где сигнал тревоги уже отключен.
Также возможно реагировать на события, которые были подняты "где-то еще" - быть в другом процессе /appdomain/process на другой машине с помощью различных механизмов. Если вам нужно было перезвонить в "где-то еще", чтобы получить требуемую информацию, это может занять несколько секунд (или меньше или больше!), Что делает передачу полезных/требуемых данных через EventArgs или производный класс массивной производительностью улучшение.
Ответ 4
Данные, переданные в EventArgs, необязательно доступны в свойствах объекта, сгенерировавшего событие. Например, в событии MouseDown MouseEventArgs содержит информацию о текущей позиции мыши. Объект, который сгенерировал это событие, вероятно, даже не сохраняет ничего такого изменчивого.
Ответ 5
Вам не нужно передавать EventArgs.Empty
обработчику. Вы можете передать любой производный класс. Когда обработчик события указан для принятия EventArgs
в качестве параметра, это означает, что нет никаких конкретных аргументов, которые всегда доступны, но вы можете захотеть передать свои данные для дополнительной информации.
Ответ 6
Еще одна приятная вещь, которую вы получаете от стандартного шаблона, - это то, что люди, использующие ваш класс, который предоставляет событие, могут подключать обычные обработчики событий:
public SomeWinFormClass() {
InitializeComponent();
_yourClassInstance = new YourClass();
someButton.Click += SomethingICareAboutHappened;
_yourClassInstance.YourEvent += SomethingICareAboutHappened;
}
private void SomethingICareAboutHappened(object sender, EventArgs e)
{
// do something -- logging, signaling a handle someone
// waiting for, etc.
}
Не нужно также объявлять, что все ваши собственные делегаты объявляют ваши события. Если вы использовали EventHandler<TEventArgs>
для объявления YourEvent, я не думаю, что вам это удастся, хотя кажется, что вы должны быть в состоянии.