Обоснование класса EventArgs - PullRequest
10 голосов
/ 17 июля 2009

Я изучаю события в C # и понимаю, что класс EventArgs содержит данные о событии. Но мне трудно понять, почему EventArgs необходим.

Например, в этом примере MSDN , не мог ли класс WakeMeUp прочитать все необходимые данные (snoozePressed, nrings) из полей AlarmClock? Если он может их установить, то почему он не может их получить?

Ответы [ 6 ]

11 голосов
/ 17 июля 2009

Преимущества класса EventArgs (на мой взгляд) в основном следующие:

  • Вы можете добавлять члены в класс EventArgs, не изменяя подпись события
  • Вы отключаете информацию, переданную в обработчик событий от экземпляра объекта

Может даже оказаться, что информация, содержащаяся в EventArgs, не раскрывается объектом, вызывающим событие.

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

9 голосов
/ 17 июля 2009

Класс EventArgs необходим, потому что, если вы хотите расширить свое событие, чтобы предоставить больше информации в будущем, у вас будут проблемы с переносимостью для всех клиентов, использующих исходную сигнатуру метода исходного события.

Например,

public void IHandleEventVersion1(string p1, int p2)
{
    ....
}

Теперь вы хотите предоставить больше информации в событии EventVersion1 выше (вы хотите включить char). Затем вам придется заставить клиента переписать свою обработку событий, чтобы она соответствовала вашим новым требованиям, например:

public void IHandleEventVersion1(string p1, int p2, char p2)
{
    ...
}

Видите, как неловко это может быть при попытке предоставить больше информации?

Итак, класс EventArgs предоставляет общий шаблон проектирования для программирования, позволяя вам и мне быстро расширять данные, которые мы хотим предоставить для события.

Общий шаблон кодирования структуры событий таков:

Основная стратегия обработки событий

  1. Определите event, на который потребители вашего класса могут подписаться
  2. Определите delegate подпись, которую объявляет событие (да, вы также можете использовать универсальную версию .NET 2.0 EventHandler, а именно EventHandler<TEventArgs>)
  3. Предоставьте метод protected virtual для наследников, которые необходимо переопределить в ответ на событие, вызываемое в базовом классе
  4. В базовом классе, который объявляет ваше событие, предоставьте базовую реализацию метода 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();
        }
    }
    
6 голосов
/ 17 июля 2009

EventArgs полезен для:

  • показывает вам состояние в момент времени , в котором произошло событие
  • повышение производительности вашего кода обработки событий путем предоставления информации о событии без необходимости запроса «третьей стороны»
  • содержит данные, которые не отображаются объектом, вызвавшим событие

Чтобы расширить первый пункт ... между вызываемым обработчиком события и чтением состояния из объекта, вызвавшего событие, могли произойти другие вещи, которые полностью изменили состояние на что-то другое. В этом случае вы будете реагировать, например, на событие AlarmHasGoneOff в AlarmClock, когда сигнал тревоги уже был отключен.

Также возможно реагировать на события, которые были инициированы «в другом месте» - будь то в другом процессе / домене приложения / процессе на другом компьютере с помощью различных различных механизмов. Если затем вам нужно было перезвонить в это «другое место», чтобы получить требуемую информацию, это может занять несколько секунд (или меньше, или больше!), Что сделает передачу полезных / необходимых данных через EventArgs или производный класс огромной производительностью. улучшение.

2 голосов
/ 17 июля 2009

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

2 голосов
/ 17 июля 2009

Данные, передаваемые в EventArgs, не обязательно доступны в свойствах объекта, который сгенерировал событие. Например, при событии MouseDown MouseEventArgs включает информацию о текущей позиции мыши. Объект, сгенерировавший это событие, вероятно, даже не хранит ничего столь изменчивого.

1 голос
/ 17 июля 2009

Еще одна приятная вещь, которую вы получаете, следуя стандартному шаблону, состоит в том, что люди, использующие ваш класс, который предоставляет событие, могут подключать общие обработчики событий:

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's 
  // waiting for, etc.
}

Также не нужно объявлять всех своих собственных делегатов для объявления ваших событий. Если вы использовали EventHandler<TEventArgs> для объявления YourEvent, я не думаю, что вам это сойдет с рук, хотя кажется, что вы должны это сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...