2009-07-17 2 views
10

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

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

ответ

11

В расквитаться с классом EventArgs является (как я вижу), главным образом, эти два:

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

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

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

+0

Последний параграф - хорошее объяснение. Благодарю. – ark

+1

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

2

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

+0

Это имеет смысл. Но нужно ли это в этом примере? – ark

+0

Да. Даже если вы можете получить данные другим способом, если следовать шаблону любого другого события .NET, тогда EventArgs должен нести данные, относящиеся к событию. –

6

EventArgs полезно:

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

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

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

+0

+1 Состояние в момент времени. Особенно для потокобезопасного кода. – jnm2

2

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

9

Класс 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. Обеспечить метод protectedvirtual для Наследники переопределять в ответ на событие, воспитывающихся в вашем базовом классе
  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(); 
        } 
    } 
    
1

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

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, я не думаю, что вам это удастся, хотя кажется, что вы должны быть в состоянии.

Смежные вопросы