example event c# .net events

example - public event c#



¿Por qué los eventos en C#toman(remitente, EventArgs)? (10)

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


Chris Anderson dice en el libro de pautas de diseño del marco:

[T] su es solo un patrón. Al tener argumentos de eventos empaquetados en una clase, obtienes una mejor semántica de versiones. Al tener un patrón común (sender, e) , se aprende fácilmente como la firma de todos los eventos.

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


El "remitente del objeto" permite reutilizar un método para múltiples objetos cuando se supone que el método del manejador debe hacer algo con el objeto que provocó el evento, por ejemplo, 3 textbox puede tener un solo manejador 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 forma más inteligente de lidiar con los eventos.


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

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

En cuanto al remitente, en algunos casos (pero no en todos) 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.


En ocasiones, le gustaría obligar a todos los usuarios de su evento a usar un parámetro de evento particular, por ejemplo, un evento de seguridad que pasa un parámetro booleano, verdadero para bueno, falso para malo. En este caso, desea que su consumidor sea muy consciente del nuevo parámetro, es decir, desea que sus consumidores se acoplen a ese parámetro. Tome nota, sus consumidores aún están desacoplados de su clase de despedida 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.


En realidad, esto es discutible si esta es o no la mejor forma de hacer 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 el remitente, y tiene que saber qué tipo de transmitir al remitente para hacer algo con él, es un anti- patrón.


Es un buen patrón de usar, de esa manera, cualquier persona que implemente el evento puede encontrar lo que lo envió.

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

Incluso si no necesita los argumentos para realizar el evento, si no los incluye con la primera ejecución del marco y desea agregarlos más tarde, rompe todas las implementaciones anteriores y tiene que volver a escribirlas. Además, si crea un marco y lo va a distribuir, empeorará porque todos los que usen el marco necesitarán refactorizarse.


Esto le permite al desarrollador consumidor la capacidad de escribir un único controlador de eventos para múltiples eventos, independientemente del remitente o 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.


La clase EventArgs por sí sola es inútil, ya que debe derivarse para crear instancias con cualquier contenido. Esto indicaría que se debe usar una subclase, y muchas ya existen en .NET. Tristemente, no puedo encontrar ninguno genérico bueno.

Digamos que quiere delegar el registro en un evento genérico ... SIN ESCRIBIR SU PROPIA EventCulse SUBCLASS. Puede parecer un ejercicio sin sentido, pero me gusta usar las funciones existentes. Puede pasar su cadena a través del argumento Objeto, pero eso va en contra de su uso previsto. Intenta encontrar una buena referencia de las subclases de EventArgs en Google, y aparecerás 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 llegue a ControlEventArgs , verá que se puede usar la propiedad Text, pero con toda la sobrecarga de un control de Windows. ConvertEventArgs puede ser útil, ya que pasa el tipo junto con los datos, pero esto aún requiere un acoplamiento ajustado que no está bien documentado ni inherentemente seguro para el tipo. DataReceivedEventArgs no tiene implementación. EntryWrittenEventArgs requiere EventLogEntry con una matriz de bytes o StreamingContext para 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 el momento, con dos cadenas y un argumento obligatorio enum de WatcherChangeTypes que PUEDEN establecerse en 0, si sabes lo que estás haciendo. LabelEditEventArgs usa un int y una cadena, si no le importa requerir el espacio de nombres Windows.Forms. RenamedEventArgs es similar a FileSystemEventArgs con una cadena adicional. Finalmente, ResolveEventArgs 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 ResolveEventArgs para el registro.


Parecía que esta era la forma de Microsoft de evolucionar el modelo de eventos a lo largo del tiempo. También parece que también permiten otra forma de hacerlo con el "nuevo" delegado de Acción y sus variaciones.


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