Основываясь на некоторых из предыдущих ответов, я собираюсь разбить свой ответ на три области.
Во-первых, физические ограничения использования Action<T1, T2, T2... >
против использования производного класса EventArgs
. Их три: во-первых, если вы изменяете количество или типы параметров, каждый метод, на который подписывается, должен быть изменен, чтобы соответствовать новому шаблону. Если это общедоступное событие, которое будут использовать сторонние сборки, и есть вероятность того, что аргументы события будут изменены, это будет причиной для использования пользовательского класса, полученного из аргументов события, для согласованности (помните, что вы МОЖЕТЕ еще используйте Action<MyCustomClass>
) Во-вторых, использование Action<T1, T2, T2... >
предотвратит передачу обратной связи BACK вызывающему методу, если у вас нет какого-либо объекта (например, со свойством Handled), который передается вместе с действием. В-третьих, вы не получаете именованные параметры, поэтому, если вы передаете 3 bool
, int
, два string
и DateTime
, вы не знаете, что означают эти значения являются. В качестве дополнительного примечания вы можете использовать метод «Безопасное выполнение этого события при использовании Action<T1, T2, T2... >
».
Во-вторых, последствия последовательности. Если у вас есть большая система, с которой вы уже работаете, почти всегда лучше следовать тому, как спроектирована остальная система, если у вас нет очень веской причины. Если у вас есть общедоступные события, которые необходимо поддерживать, возможность замены производных классов может быть важной. Имейте это в виду.
В-третьих, в реальной жизни я лично обнаружил, что склонен создавать множество разовых событий для таких вещей, как изменения свойств, с которыми мне нужно взаимодействовать (особенно при работе с MVVM с моделями представления, которые взаимодействуют друг с другом) или где событие имеет один параметр. В большинстве случаев эти события принимают форму public event Action<[classtype], bool> [PropertyName]Changed;
или public event Action SomethingHappened;
. В этих случаях есть два преимущества. Сначала я получаю тип для класса выдачи. Если MyClass
объявляет и является единственным классом, запускающим событие, я получаю явный экземпляр MyClass
для работы в обработчике событий. Во-вторых, для простых событий, таких как события изменения свойств, значение параметров очевидно и указано в имени обработчика событий, и мне не нужно создавать множество классов для событий такого типа.