Pregunta

Se sabe que se deben declarar eventos que tomen como parámetros (object sender, EventArgs args).¿Por qué?

¿Fue útil?

Solución

Esto permite al desarrollador consumidor la capacidad de escribir un único controlador de eventos para múltiples eventos, independientemente del remitente o el evento.

Editar: ¿Por qué necesitarías un patrón diferente?Puede heredar EventArgs para proporcionar cualquier cantidad de datos, y cambiar el patrón solo servirá para confundir y frustrar a cualquier desarrollador que se vea obligado a consumir este nuevo patrón.

Otros consejos

En realidad, es discutible si esta es o no la mejor forma de realizar eventos.Existe la escuela de pensamiento de que, como los eventos están destinados a desacoplar dos segmentos de código, el hecho de que el controlador de eventos obtenga al remitente y tenga que saber en qué tipo convertir al remitente para poder hacer algo con él es un anti- patrón.

Porque es un buen patrón para cualquier mecanismo de devolución de llamada, independientemente del idioma.Quiere saber quién envió el evento (el remitente) y los datos pertinentes al evento (EventArgs).

El uso de un único parámetro, EventArgs, para los datos pasados ​​por un evento le permite agregar datos a su evento en versiones futuras de su software sin afectar a los consumidores existentes.Simplemente agrega nuevos miembros a una clase derivada de EventArgs existente o crea una clase derivada con los nuevos miembros.

De lo contrario, la coherencia y el principio de mínima sorpresa justifican el uso de EventArgs para pasar datos.

En cuanto al remitente, en algunos (pero no en todos) casos es útil saber qué tipo envió el evento.Usar un tipo distinto de objeto para el argumento del remitente es demasiado restrictivo:significaría que otros remitentes no podrían reutilizar la misma firma del evento.

Es un buen patrón para usar, de esa manera, quien implemente el evento puede encontrar lo que lo estaba enviando.

Además, el mejor método es anular EventArgs y pasar datos a través de ellos.Los EventArgs son una clase base.Si observa varios controles que llaman a eventos, han anulado EventArgs, lo que le brinda más información sobre el evento.

Incluso si no necesita los argumentos para realizar el evento, si no los incluye en la primera ejecución del marco y desea agregarlos más tarde, romperá todas las implementaciones anteriores y tendrá que reescribirlas.Además, si crea un marco y lo va a distribuir, empeora porque todos los que usan su marco necesitarán refactorizarlo.

Chris Anderson dice en el libro Pautas de diseño de marcos:

[Esto] se trata sólo de un patrón.Al tener argumentos de eventos empaquetados en una clase, se obtiene una mejor semántica de versiones.Al tener un patrón común (sender, e) se aprende fácilmente como firma para todos los eventos.

Hay situaciones que involucran principalmente interoperabilidad que requerirían una desviación de este patrón.

Parecía que esta era la forma en que Microsoft hacía evolucionar el modelo de eventos con el tiempo.También parece que también están permitiendo otra forma de hacerlo con el "nuevo" delegado de acción y sus variaciones.

El "remitente de objetos" permite reutilizar un método para múltiples objetos cuando se supone que el método del controlador debe hacer algo con el objeto que generó el evento; por ejemplo, 3 cuadros de texto pueden tener un solo controlador que restablecerá el texto del cuadro de texto de activación.

La principal ventaja de EventArgs es que permite refactorizar la información del evento sin la necesidad de cambiar las firmas de todos los manejadores en todos los proyectos que estén suscritos a este tipo de evento.

No puedo pensar en una manera más inteligente de lidiar con los eventos.

A veces le gustaría obligar a todos sus consumidores de eventos a utilizar un parámetro de evento particular, por ejemplo, un evento de seguridad que pasa un parámetro booleano, verdadero para bien, falso para mal.En este caso, desea que su consumidor sea consciente del nuevo parámetro, es decir,desea que sus consumidores se combinen con ese parámetro.Tome nota, sus consumidores todavía están desacoplados de su clase de activación de eventos, pero no de su evento.

Sospecho que este escenario se aplica a una gran cantidad de casos y en esos casos el valor de EventArgs se reduce considerablemente.

El Argumentos de eventos La clase por sí sola es inútil ya que debe derivarse para crear una instancia con cualquier contenido.Esto indicaría que se debe utilizar una subclase, y muchas ya existen en .NET.Lamentablemente, no puedo encontrar ninguno genérico bueno.

Digamos que desea delegar el registro a un evento genérico...SIN ESCRIBIR TU PROPIA SUBCLASE EventArgs.Puede parecer un ejercicio inútil, pero me gusta utilizar las funciones existentes.Puede pasar su cadena a través del argumento Objeto, pero eso va en contra de su uso previsto.Intente encontrar una buena referencia de las subclases de EventArgs en Google y se quedará seco.(Al menos yo lo hice).

ReSharper ayuda un poco, ya que cuando escribe "EventArgs" verá una lista de todas las clases (dentro de su alcance de uso/importaciones) que CONTIENEN la cadena "EventArgs".Al examinar la lista, verá muchas clases sin miembros de cadena.cuando llegues a ControlEventArgs, verá que se puede usar la propiedad Texto, pero con toda la sobrecarga de un control de Windows. ConvertirArgsEventos podría ser útil, ya que pasa el tipo junto con los datos, pero esto aún requiere un acoplamiento estrecho que no está bien documentado ni es inherentemente seguro para los tipos. Argumentos de eventos recibidos de datos no tiene implementación. EntradaWrittenEventArgs requiere un EventLogEntry con una matriz de bytes o StreamingContext para los datos. ErrorEventArgs está más cerca, con un mensaje de Excepción, si no le importa llamar a todos sus eventos de registro Exception ErrorEvents internamente. FileSystemEventArgs es probablemente el más cercano hasta ahora, con dos cadenas y un argumento de enumeración WatcherChangeTypes requerido que PUEDE establecerse en 0, si sabes lo que estás haciendo. EtiquetaEditarArgumentos de evento usa un int y una cadena, si no le importa requerir el espacio de nombres Windows.Forms. ArgsEventArgs renombrados es similar a FileSystemEventArgs con una cadena adicional.Finalmente, resolverArgsEvent en System.Runtime.InteropServices pasa una sola cadena.Hay otras bibliotecas, pero me quedé con algunas de las más comunes.Entonces, dependiendo de la implementación, puedo usar ErrorEventArgs, FileSystemEventArgs o resolverArgsEvent para iniciar sesión.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top