Я сосредоточусь на втором пункте.Как указал Джон, вы можете использовать своих собственных делегатов для проведения мероприятий.Но вы редко должны.Даже если вам не нужны соглашения, посмотрите на это так: всякий раз, когда вы используете свои собственные события с пользовательскими делегатами, у вас есть следующий код, кроме самого поля события:
- Ваш пользовательский делегат
- Обработчики событий (методы с совпадающей сигнатурой) - иногда их много
- Точки вызова событий (где вам нужно передать все параметры) - иногда aМногие из них
- Я также склонен создавать
InvokeMyEvent
методы, которые выполняют проверку на ничтожность и другие вещи, которые необходимо сделать
Вы должны изменить все это если вы решите добавить или удалить параметр или изменить тип параметра.
Теперь, если вы создаете свой собственный класс, который наследует EventArgs
, или используете EventArgs<T>
, у вас есть:
- Ваш
CustomEventArgs
класс - Обработчики событий
- Точки вызова событий
InvokeMyEvent
методы.
Всякий раз, когда вы решите изменить аргументы события, у вас будет наизмените только свой собственный класс аргументов и некоторые точек вызова события.«Некоторые», потому что вы можете предоставить подходящие значения по умолчанию для полей вашего класса args и предоставлять значения только тогда, когда вам это нужно.
Большинство разговоров о хорошей / плохой практике сосредоточены на одном - easyизменения .Изменения всегда происходят.Чем меньше вещей, которые вы должны изменить, когда они делают, тем лучше.У дизайна много итераций, и есть вероятность, что вам придется много менять интерфейсы и типы.Вы не хотите менять десятки подписей, когда решаете, что вам больше не нужен этот параметр.Поэтому используйте EventArgs
или EventArgs<T>
и избавьте себя от головной боли.
Еще один незначительный момент заключается в том, что вы, вероятно, захотите объявить некоторые методы, которые заботятся о вызове событий, например:
public static public void FireEvent<T>(this EventHandler handler, object sender, EventArgs<T> e)
where T : EventArgs
{
if (handler != null)
handler(sender, e);
}
Если все ваши события основаны на EventHandler
, вы можете использовать один универсальный метод для подобных вещей.Если нет, то в конечном итоге их будет десятки.