Подтвердить что ты не робот

Почему * должен * использовать EventHandler

Я ненавижу EventHandler. Я ненавижу, что мне нужно приложить sender, если я хочу что-то с этим сделать. Я ненавижу, что мне нужно сделать новый класс, наследующий от EventArgs, чтобы использовать EventHandler<T>.

Мне всегда говорили, что EventHandler - это традиция и бла, бла... что угодно. Но я не могу найти причину, почему эта догма все еще существует.

Есть ли причина, по которой было бы неплохо создать новый делегат:

delegate void EventHandler<TSender, T>(TSender sender, T args);

Таким образом, sender будет типичным, и я могу передать все, что мне нужно, в качестве аргументов (включая пользовательские EventArgs, если я так желаю).

4b9b3361

Ответ 1

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

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

Например, если вы объявляете обработчик как тип int -> void, тогда сторонний код может вставлять в очередь YourEvent += Enviroment.Exit(-1) и вы можете случайно выйти из процесса. Это, очевидно, вызовет проблему с легким обнаружением, но есть гораздо больше вредоносных API, которые могут быть выставлены в очередь, чтобы делать другие вещи.

Когда подпись (object, EventArgs) -> void, тогда в инфраструктуре нет привилегированных операций, которые могут быть выставлены в очередь, потому что ни одна из них не совместима с этой сигнатурой. Это часть обзора кода безопасности в рамках для обеспечения этого (к сожалению, я не могу найти источник, где я его читал).

Таким образом, в определенных обстоятельствах существуют обоснованные соображения безопасности относительно того, почему вы должны использовать стандартный шаблон. Если вы на 100% уверены, что ваш код никогда не будет использоваться в этих обстоятельствах, тогда руководство по сигнатуре событий не так важно (помимо других разработчиков, которые думают о WTF), но если это возможно, вы должны следовать за ним.

Ответ 2

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

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

Ответ 3

Я обычно использую типы Action<...> как обработчики событий - если вам не нужно взаимодействовать с другим кодом (или дизайнером), который специально требует EventHandler, нет причин для его использования.

Ответ 4

Хорошо, что все это кастинг необычно, клиентский код довольно часто уже знает, кто отправитель, потому что он явно подписал событие только для одного объекта. Обмен обработчиками событий довольно редок. Если общее поведение желательно, то лучшим подходом является вывод из класса и переопределение метода OnXxxx. Тогда вы больше не заботитесь о отправителе, вы получили это.

Но решите свою проблему тривиально, включив безопасную ссылку на отправителя в свой собственный производный класс EventArgs.

Ответ 5

Я согласен с вами, соглашение глупо и/или устарело. Сделайте это правильно, с надлежащей безопасностью типа и дженериками.

Это все время, что у вас есть задача сделать, и вы можете следить за тем, как последний парень сделал это или сделать это по-другому, что, по вашему мнению, возможно, лучше.

Первый выбор обычно выбирается - делайте это так же, как и последний парень, и у вас не будет проблем. Но второй вариант - это то, что улучшает программное обеспечение в долгосрочной перспективе. (Или, по крайней мере, он может улучшить его, если вы правы, что ваш путь лучше!:))

Ответ 6

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

Использование EventHandler делегата - это руководство, представленное здесь: http://msdn.microsoft.com/en-us/library/ms229011.aspx