Я собираюсь раскачивать лодку здесь и предложить что-то совершенно еретическое.Раньше я был в лагере EventArgs
, потому что я цеплялся за менталитет «MS рекомендует это, и так всегда делали», но со временем я стал ненавидеть EventArgs
.Почему?
- Это продвигает стиль кодирования .NET-1.0ish, который основан на слабой типизации / приведении типов и заставляет меня чувствовать себя нечистым.
- Это заставляет ваш класс, который реализуетсобытие, которое загрязняет кучу новыми
EventArg
экземплярами каждый раз, когда она срабатывает, что также делает меня неловким.Почему бы не сделать так, чтобы мои события давали подписчикам именно то, что им нужно, вместо того, чтобы помещать их в дополнительный класс, который ничего не делает для меня. - Подписи ваших методов обратного вызова, которые подписываются на событие, выглядят как мусор и имеют очень малосемантическая деталь - например,
object sender
- ЧТО является отправителем?!?!
Теперь я объявляю своих собственных делегатов обработчиков событий, которые я аккуратно храню в своих собственных "Папка "Делегаты" в моем решении, а также их собственное пространство имен.Поэтому мой делегат может находиться в своем собственном файле, например так:
namespace MyAPI.Data.Delegates
{
public delegate void DataEventHandler<TData>(DataFeed<TData> sender, TData data);
}
Объявление события теперь выглядит следующим образом:
public event DataEventHandler<TData> DataReady = delegate { };
Преимущества этого подхода:
- Сигнатуры метода имеют более семантическую детализацию.Вы знаете, ВОЗ отправляет ЧТО .
- Сохраняется строгая типизация.Больше не нужно приводить
object sender
к тому, что, как вы думаете, должно быть. - Вам не нужно
new()
поднимать объекты и загрязнять кучу, что может быть проблематично, если ваше событие часто срабатывает.Просто передайте своим подписчикам именно то, что им нужно, будь то ссылка на объект или тип значения. - Используя соглашение об именовании
___EventHandler
для своих делегатов, вы все равно продвигаете унифицированный стиль для своего кода, который делаетпользователям вашего API легко узнать, каковы ваши намерения.
Единственный "недостаток" заключается в том, что пользователям вашего кода трудно связать ваше событие с существующими методами, которые имеютobject sender, EventArgs e
подпись.Однако этот момент спорный, потому что если ваше событие доставляет какие-либо дополнительные данные (например, вы создали собственный подкласс EventArgs
), тогда им все равно придется изменить сигнатуру метода (или привести к вашему типу подкласса).В любом случае, это все еще противно.
Вот почему мне нравится мой путь.