Итак, я начал экспериментировать с FxCop в последнее время и заметил одну вещь: он настаивает на том, что любой метод, прикрепленный к событию, должен быть в форме
void Callback(object sender, EventArgs args) { ...}
и быть привязанным к
MyObject.Event += new EventHandler(Callback);
Теперь все было хорошо и хорошо еще в дни .Net 1.1, но с 3.5 я обнаружил, что намного проще и интуитивно понятнее просто сделать вызов события типа Action или одного из его обобщений и написать метод точно так, как я было бы, если бы он был вызван явно; ни один из отправителей этого объекта или неумелого EventHandler.
Я считаю, что это абсолютный императив дизайна. Если вы проектируете метод для обратного вызова события по-другому, это означает, что метод, по крайней мере, неявно имеет некоторую информацию о своем вызове - это серьезный недостаток!
Я полностью согласен с тем, что могу чего-то упустить. Что вы думаете по этому поводу, FxCop ошибается или я?





Я не думаю, что FxCop обновлялся достаточно давно; Вы пробовали это с помощью инструментов анализа кода VS2008 (преемника FxCop)?
Вы должны следовать соглашению.
Используйте общий EventHandler <T>, где T является EventArgs или является производным от него. Подключите мероприятие с
MyObject.SomeEvent + = новый обработчик событий <EventArgs> (SomeMethod);
Метод обработчика событий должен возвращать void (нет смысла возвращать что-либо в средство повышения событий), и следует соблюдать соглашение о получении объекта-отправителя с данными в аргументах события.
Причины "хрени" (sender и eventargs)
Картина продолжается и дальше. Вы также должны вызвать свое событие SomeEvent в защищенном методе с именем OnSomeEvent (), чтобы производные от вашего класса могли делать такие вещи, как подавление событий, их создание в потокобезопасном режиме, запускать их в потоке пользовательского интерфейса, вызывать их с тайм-аутами. или защита от исключений, процессы регистрации событий и т. д.
Эй, это не идеальный шаблон (возможно, отправитель мог быть помещен в аргументы события), но почти весь код .Net следует за ним, и код фреймворка всегда следует за ним. Почему бы и не подписаться.
Вероятно, поэтому он существует. Однако это не обязательно означает, что появление дженериков сделало его бесполезным или плохим.
Конвенция - Итак? Расширяемость - не все так просто. Знание вызывающего абонента - может быть полезно, и в этом случае это может быть аргумент (строго типизированный), он не должен быть обязательным. Кажется, что это существует, потому что на момент его изобретения не было дженериков.