При программировании событий на C # рекомендуется создать делегат в форме:
delegate XEventHandler(object sender, XEventArgs e);
У меня вопрос по первому аргументу делегата object sender
. Это всегда должно быть универсальным object
? Наличие отправителя типа object
всегда приводит к коду, подобному этому.
val = ((ConcreteType)sender).Property;
или, еще более многословный,
ConcreteType obj = sender as ConcreteType
if (obj != null) { ... }
Один аргумент против строго типизированных отправителей заключается в том, что другие объекты могут пересылать событие, не заботясь о типе. Хотя это может иметь смысл в средах с графическим интерфейсом, я не уверен, что это может принести пользу вне графического интерфейса.
Что если класс отправителя всегда известен (по крайней мере, как абстрактный класс)? Например, если я реализую ListChanged
событие в абстрактном List
классе и если другие классы собираются его унаследовать (например LinkedList
, ArrayList
), можно ли определить мой делегат с отправителем типа List
?
delegate ListChangedEventHander(List sender, ListChangedEventArgs e);
Или есть ли обратная сторона в изменении обычного типа object sender
на более конкретный?
System.Windows.Forms
пространство имен - это место, где события используются наиболее интенсивно, и имело смысл подписаться наClick
событиеButton
илиCheckBox
. Таким образом, отправитель должен быть общим. ...List
s.Причиной рекомендации является то, что она учитывает будущие изменения, которые не обязательно требуют изменений в существующем коде, и особенно в публичном интерфейсе.
Сам механизм событий все еще можно использовать для событий в стиле "VB6", но вам придется изменить всех существующих потребителей, если вам когда-либо понадобится изменить сигнатуру (или, что еще хуже, создать новые версии тех же событий). При рекомендуемом подходе, поскольку более новые элементы наследуют от существующих, вы можете обновить подпись, не исправляя существующий код.
источник