Упаковка аргументов события в класс, зачем?

Большинство стоковых событий .NET имеют такую сигнатуру:

delegate void SomethingSomething(SomethingEventArgs e);
event SomethingSomething OnSomethingSomething;

и

class SomethingEventArgs
{
    public string Name;
    public int Index;
    public double Groar;
}

Почему это лучше (очевидно, так и есть, иначе любой решил бы сделать), чем:

delegate void SomethingSomething(string Name, int Index, double Groar);
event SomethingSomething OnSomethingSomething;

поскольку вам не нужно упаковывать параметры в объект, а без инициализаторов (.NET 2.0) это было своего рода упражнением по набору текста.

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

Итак, почему?

24
задан Daniel Mošmondor 25 November 2011 в 14:30
поделиться

4 ответа

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

Редактировать: в соответствии с комментариями я расскажу о том, как это влияет на сокращение критических изменений.

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

11
ответ дан 28 November 2019 в 22:21
поделиться

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

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

Другим примером является класс ObjectDataSource, который позволяет клиенту предоставлять экземпляр объекта, когда он требуется. Это делается путем подписки на событие ObjectDataSource.ObjectCreating и предоставления экземпляра объекта путем установки члена EventArgs.

6
ответ дан 28 November 2019 в 22:21
поделиться

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

По Microsoft:

  • Тип возврата Void.

  • Первый параметр называется отправителем и имеет тип Object. Это объект, который вызвал событие.

  • Второй параметр называется e и имеет тип EventArgs или производный класс EventArgs. Это специфичные для события данные.

  • Метод принимает ровно два параметра.

Однако, чтобы получить больше информации по вашему вопросу, я думаю, что обоснование использования EventArgs двоякое:

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

Для получения дополнительной информации см. Дополнительную информацию от Microsoft:

  1. Подробнее о том, как разрабатывать события: http://msdn.microsoft.com/en-us/ library / ms229011.aspx
  2. Подробное руководство по использованию этого шаблона: http://msdn.microsoft.com/en-us/library/w369ty8x.aspx
3
ответ дан 28 November 2019 в 22:21
поделиться

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

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

В то же время вы можете предлагать несколько значений [out], и вам не нужно жонглировать возвращаемыми значениями или параметрами [ref], что значительно усложняет процесс многоадресной рассылки. Это также гарантирует, что любая логика проверки происходит в подклассе EventArgs, а НЕ в классе, который генерирует события.

1
ответ дан 28 November 2019 в 22:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: