Являются ли обратные вызовы событий с параметрами (object, EventArgs) пережитком 1.1 и WinForms?

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

void Callback(object sender, EventArgs args) { ...}

и быть привязанным с

MyObject.Event += new EventHandler(Callback);

Теперь все было хорошо в те времена .Net 1.1, но начиная с 3.5 я обнаружил, что гораздо проще и интуитивно проще просто вызывать событие типа Action или один из его обобщений и писать метод точно так же, как я. был бы, если бы он был вызван явно; ни один из этих отправителей объекта или EventHandler не занимался.

В сущности, я считаю, что это категорический императив дизайна. Если вы разрабатываете метод по-другому для обратного вызова события, это означает, что метод по крайней мере неявно имеет некоторую информацию о своем вызове - это главное нет-нет!

Я полностью готов принять то, что я что-то упускаю. Что вы, ребята, думаете по этому поводу, FxCop не прав или я?

13.12.2008 15:50:23
2 ОТВЕТА

Я не думаю, что FxCop был обновлен в течение длительного времени; Вы пробовали это с инструментами анализа кода VS2008 (преемник FxCop)?

0
13.12.2008 17:43:32

Вы должны следовать соглашению.

  1. Используйте универсальный EventHandler <T>, где T является или происходит от EventArgs. Подключите событие с

    MyObject.SomeEvent + = new EventHandler <EventArgs> (SomeMethod);

  2. Метод обработчика события должен возвращать void (не имеет смысла возвращать что-либо обработчику событий), и следует придерживаться соглашения о получении объекта отправителя с данными в аргументах события.

Причины "дерьма" (отправитель и eventargs)

  • условность
  • Расширяемость легче реализовать (как класс, который вызывает событие, так и класс, который его обрабатывает)
  • Иногда вы хотите знать, кто послал событие.
  • Любые / все данные могут быть заключены в аргументы события.
  • Вы можете использовать один и тот же обработчик событий для многих событий.

Картина продолжается дальше. Вы также должны вызвать ваше событие SomeEvent в защищенном методе с именем OnSomeEvent (), чтобы производные вашего класса могли делать такие вещи, как подавление событий, вызывать их потокобезопасным способом, поднимать их в потоке пользовательского интерфейса, поднимать их с тайм-аутами или защита от исключений, процессы регистрации событий и т. д.

Эй, это не идеальный шаблон (возможно, отправитель мог быть помещен в аргументы событий), но почти весь код .Net следует за ним, а код фреймворка всегда следует за ним. Почему бы и не следовать?

1
13.12.2008 18:56:48
Конвенция - так? Расширяемость - не так уж и просто. Знание вызывающей стороны - может быть полезно, в этом случае это может быть аргумент (строго типизированный), он не должен быть обязательным. Просто кажется, что это существует, потому что в то время, когда они его изобрели, не было дженериков
George Mauer 14.12.2008 15:06:07
Это, вероятно, причина, по которой он существует. Это не обязательно означает, что появление дженериков делает его бесполезным или плохим.
technophile 14.12.2008 17:39:53