Al programar eventos en C #, se recomienda crear un delegado en forma de:
delegate XEventHandler(object sender, XEventArgs e);
Mi pregunta es sobre el primer argumento del delegado, object sender
. ¿Siempre tiene que ser un genérico object
? Tener un remitente de tipo object
siempre da como resultado un código similar a este.
val = ((ConcreteType)sender).Property;
o, incluso más detallado,
ConcreteType obj = sender as ConcreteType
if (obj != null) { ... }
Un argumento contra los remitentes fuertemente tipados es que otros objetos pueden reenviar el evento sin preocuparse por el tipo. Si bien esto puede tener sentido en entornos de GUI, no estoy seguro de si podría beneficiarse fuera de una GUI.
¿Qué sucede si la clase del remitente siempre se conoce (al menos como una clase abstracta)? Por ejemplo, si estoy implementando un ListChanged
evento en una List
clase abstracta , y si otras clases lo van a heredar (por ejemplo LinkedList
, ArrayList
), ¿está bien definir mi delegado con un remitente de tipo List
?
delegate ListChangedEventHander(List sender, ListChangedEventArgs e);
O, ¿habría una desventaja de cambiar el convencional object sender
a un tipo más específico?
System.Windows.Forms
espacio de nombres es el lugar donde los eventos se usan con mayor frecuencia, y tenía sentido suscribirse alClick
evento deButton
o aCheckBox
. Por lo tanto, el remitente debe ser genérico. ...List
s.La razón de la recomendación es que permite cambios futuros que no necesariamente requieren cambios en el código existente, y especialmente en la interfaz pública.
El mecanismo de evento en sí mismo puede usarse para eventos de estilo "VB6", pero tendrá que cambiar todos los consumidores existentes si alguna vez necesita cambiar la firma (o peor: crear nuevas versiones de los mismos eventos). Con el enfoque recomendado, siempre que los elementos más nuevos hereden de los existentes, puede actualizar la firma sin corregir el código existente.
fuente