Почему события в C # должны происходить (sender, EventArgs)?

StackOverflow https://stackoverflow.com/questions/104674

  •  01-07-2019
  •  | 
  •  

Вопрос

Известно, что вы должны объявлять события, которые принимают в качестве параметров (object sender, EventArgs args).Почему?

Это было полезно?

Решение

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

Редактировать: Зачем вам нужен другой шаблон?Вы можете наследовать EventArgs для предоставления любого объема данных, и изменение шаблона приведет только к путанице и разочарованию любого разработчика, который вынужден использовать этот новый шаблон.

Другие советы

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

Потому что это хороший шаблон для любого механизма обратного вызова, независимо от языка.Вы хотите знать, кто отправил событие (the sender) и данные, имеющие отношение к событию (EventArgs).

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

В противном случае согласованность и принцип наименьшей неожиданности оправдывают использование EventArgs для передачи данных.

Что касается отправителя, то в некоторых (но не во всех) случаях полезно знать, какой тип отправил событие.Использование типа, отличного от object, в качестве аргумента отправителя является слишком ограничительным:это означало бы, что другие отправители не смогли бы повторно использовать ту же сигнатуру события.

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

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

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

Крис Андерсон говорит в книге "Рекомендации по разработке фреймворков":

[T] его речь идет всего лишь о шаблоне.Имея аргументы события, упакованные в классе, вы получаете лучшую семантику управления версиями.Благодаря наличию общего шаблона (sender, e) его легко узнать как подпись для всех событий.

Существуют ситуации, в основном связанные с взаимодействием, которые потребовали бы отклонения от этого шаблона.

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

"Отправитель объекта" позволяет повторно использовать один метод для нескольких объектов, когда метод обработчика должен что-то делать с объектом, который вызвал событие, например, 3 текстовых поля могут иметь один единственный обработчик, который сбросит текст запускающего текстового поля.

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

Я не могу придумать более разумного способа справиться с событиями.

Иногда вы хотели бы заставить всех ваших потребителей событий использовать определенный параметр события, например, событие безопасности, которое передает логический параметр, true для хорошего, false для плохого.В этом случае вы хотите, чтобы ваш потребитель был до боли осведомлен о новом параметре, т.е.вы хотите, чтобы ваши потребители были связаны с этим параметром.Обратите внимание, ваши потребители по-прежнему не связаны с классом запуска вашего мероприятия, но не с самим мероприятием.

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

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

Допустим, вы хотите делегировать ведение журнала общему событию...БЕЗ НАПИСАНИЯ СОБСТВЕННОГО ПОДКЛАССА EventArgs.Это может показаться бессмысленным упражнением, но мне нравится использовать существующие функции.Вы можете передать свою строку через аргумент Object, но это противоречит ее предполагаемому использованию.Попробуйте найти хорошую ссылку на подклассы EventArgs в Google, и вы ничего не найдете.(По крайней мере, я это сделал.)

ReSharper немного помогает, поскольку при вводе "EventArgs" вы увидите список всех классов (в пределах вашей области использования / импорта), которые СОДЕРЖАТ строку "EventArgs".Просмотрев список, вы увидите множество классов без строковых элементов.Когда ты доберешься до ControlEventArgs ( контрольные значения ), вы видите, что свойство Text может быть использовано, но со всеми накладными расходами элемента управления Windows. ConvertEventArgs Преобразовывать значения может быть полезно, поскольку вы передаете тип вместе с данными, но это по-прежнему требует тесной связи, которая не является ни хорошо документированной, ни типобезопасной по своей сути. DataReceivedEventArgs DataReceivedEventArgs не имеет реализации. Entrywriteneventargs требуется EventLogEntry с массивом байтов или StreamingContext для данных. ErrorEventArgs ( Ошибка EventArgs ) ближе, с сообщением об исключении, если вы не возражаете вызывать все события вашего журнала Exception ErrorEvents внутренне. Файловая система EventArgs вероятно, это самый близкий вариант, с двумя строками и обязательным аргументом перечисления WatcherChangeTypes, который МОЖЕТ быть установлен в 0, если вы знаете, что делаете. LabelEditEventArgs Помеченные значения использует int и строку, если вы не возражаете, требуя пространство имен Windows.Forms. Переименованные EventArgs аналогичен FileSystemEventArgs с дополнительной строкой.Наконец-то, Разрешающие значения в System.Runtime.InteropServices передает единственную строку.Есть и другие библиотеки, но я остановился на некоторых из наиболее распространенных.Итак, в зависимости от реализации я могу использовать ErrorEventArgs ( Ошибка EventArgs ), Файловая система EventArgs или Разрешающие значения для ведения журнала.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top