Comprensión de eventos en C#
Los eventos en C# son un concepto fundamental que muchos desarrolladores utilizan pero que quizá no entiendan del todo, sobre todo cuando se trata de crear sus propios eventos. Tim Corey ofrece una guía completa sobre cómo crear y utilizar eventos, explorando las mejores prácticas y características avanzadas en su vídeo "C# Events - Creating and Consuming Events in Your Application".
En este artículo, vamos a explorar los eventos de C#, centrándonos en su sintaxis, cómo se definen y cómo ayudan a resolver problemas comunes de programación utilizando los ejemplos en vídeo de Tim Corey. Comprender la gestión de eventos en C# es esencial para crear aplicaciones con capacidad de respuesta, y este artículo le ayudará a comprender los conceptos básicos del registro de errores personalizado, la gestión de excepciones y la programación basada en eventos.
Introducción a los eventos
En C# y en los lenguajes de programación, los eventos desempeñan un papel fundamental en la programación basada en eventos, ya que permiten a las aplicaciones responder a acciones como interacciones del usuario o cambios en el sistema. En comparación con otros lenguajes de programación, C# ofrece un enfoque estructurado para el manejo de eventos, lo que lo hace ideal para aplicaciones rápidas y pequeñas. Los eventos en C# se desencadenan mediante acciones específicas, y estas acciones invocan a los manejadores de eventos correspondientes para realizar las tareas deseadas.
Tim comienza explicando que la mayoría de los desarrolladores están familiarizados con los eventos en C#, pero pueden no saber cómo crear eventos personalizados. El objetivo del vídeo es presentar los eventos, explicar cómo crear eventos personalizados, hablar de sus características y describir las mejores prácticas.
Paseo por la aplicación demo
Tim utiliza una sencilla aplicación bancaria construida con Windows Forms (WinForms) para demostrar los eventos. La aplicación simula las operaciones bancarias básicas de un cliente, incluida la consulta de saldos y el registro de transacciones.
-
Resumen de la aplicación:
- La aplicación tiene dos formularios: uno para mostrar saldos de cuentas y transacciones, y otro para registrar nuevas transacciones.
- Incluye botones para simular compras con tarjeta de crédito y gestionar descubiertos transfiriendo fondos de la cuenta de ahorros a la cuenta corriente.
-
Formato principal:
- Muestra el nombre del cliente y los saldos de sus cuentas corrientes y de ahorro.
- Muestra listas de transacciones para ambas cuentas.
- Contiene un botón para abrir el formulario de registro de transacciones.
-
Formulario de transacción:
- Permite al usuario introducir los importes de las transacciones.
- Simula la realización de compras y gestiona los descubiertos transfiriendo fondos de la cuenta de ahorros a la cuenta corriente.
Código de la aplicación de demostración
Tim explica el código backend de la aplicación bancaria de demostración:
-
Clase de cliente:
- Representa a un cliente con propiedades para el nombre del cliente y dos cuentas (corriente y ahorros).
- La clase Cliente es sencilla, pero sirve como un buen punto de partida para entender cómo gestionar varias cuentas.
-
Clase de cuenta:
- Gestiona los detalles de una cuenta bancaria, incluidos el nombre de la cuenta, el saldo y la lista de transacciones.
- La propiedad Balance es de tipo decimal para cálculos monetarios precisos.
- La propiedad Transactions es una lista de sólo lectura para evitar modificaciones externas.
-
Gestión de depósitos y pagos:
- Método AddDeposit: Añade un depósito a la cuenta, actualiza el saldo y registra la transacción.
- Método MakePayment: Gestiona las retiradas de fondos, incluyendo la comprobación de fondos suficientes y la gestión de la protección contra sobregiros mediante la transferencia de fondos desde una cuenta de respaldo si es necesario.
-
Protección contra sobregiros:
- La aplicación incluye lógica para gestionar descubiertos. Si el saldo de la cuenta corriente es insuficiente para una transacción, la aplicación consulta la cuenta de ahorros para cubrir el déficit. Si el saldo combinado es suficiente, transfiere la cantidad requerida a la cuenta corriente y completa la transacción.
Para ver ejemplos de código, puede consultar directamente el vídeo de Tim Corey en el que explica el código desde el minuto 3:18 hasta el 18:27.
Evento: Clic de botón
En esta sección, Tim Corey se sumergió en el funcionamiento de los eventos de clic de botón en Windows Forms, explicando cómo se conectan estos eventos y cómo funcionan.
Comprensión de los eventos de clic de los botones
Tim comienza explicando el concepto familiar de eventos de clic de botón en aplicaciones Windows Forms. Al hacer doble clic en un botón del diseñador, Visual Studio genera automáticamente un método controlador de eventos para el evento de clic.
-
Método de gestión de eventos:
- Este método se ejecuta cada vez que se hace clic en el botón. Es donde se coloca el código que debe ejecutarse en respuesta al clic del botón.
private void recordTransactionButton_Click(object sender, EventArgs e) { // Code to handle the button click event }private void recordTransactionButton_Click(object sender, EventArgs e) { // Code to handle the button click event } -
Cableado del evento :
- El método de control de eventos está conectado al evento de clic del botón en el archivo de diseño del formulario (FormName.Designer.cs). Esto se hace utilizando el operador += para añadir el controlador de eventos al evento de clic del botón.
this.recordTransactionButton.Click += new System.EventHandler(this.recordTransactionButton_Click);this.recordTransactionButton.Click += new System.EventHandler(this.recordTransactionButton_Click);
Creación e invocación de eventos personalizados
Tim explica cómo crear eventos personalizados en C#, empezando por la clase Account, donde se activarán los eventos.
-
Definición de un evento:
- Un evento se define mediante la palabra clave event. Su aspecto es similar al de una variable pública, pero es específica para eventos.
public event EventHandler<string> RaiseTransactionApprovedEvent;public event EventHandler<string> RaiseTransactionApprovedEvent; -
Desencadenante del evento:
- Los eventos se activan mediante el método Invoke, normalmente dentro de la clase que define el evento. El método Invoke toma dos parámetros: el remitente (usualmente
this) y los datos del evento (en este caso, una cadena).
private void OnTransactionApproved(string transactionName) { RaiseTransactionApprovedEvent?.Invoke(this, transactionName); }private void OnTransactionApproved(string transactionName) { RaiseTransactionApprovedEvent?.Invoke(this, transactionName); } - Los eventos se activan mediante el método Invoke, normalmente dentro de la clase que define el evento. El método Invoke toma dos parámetros: el remitente (usualmente
-
Cableado y manejo de eventos:
- Suscríbase al evento utilizando el operador += y defina un método para gestionar el evento cuando se produzca.
account.RaiseTransactionApprovedEvent += Account_RaiseTransactionApprovedEvent; private void Account_RaiseTransactionApprovedEvent(object sender, string e) { // Code to handle the event }account.RaiseTransactionApprovedEvent += Account_RaiseTransactionApprovedEvent; private void Account_RaiseTransactionApprovedEvent(object sender, string e) { // Code to handle the event }
Uso de eventos para actualizar la interfaz de usuario
Tim explica cómo utilizar eventos para actualizar automáticamente la interfaz de usuario del navegador cuando se producen determinadas acciones, como la aprobación de una transacción.
-
Eventos de recaudación:
- Activar el evento personalizado después de que se apruebe una transacción.
public void AddDeposit(decimal amount, string depositName) { // Code to add deposit RaiseTransactionApprovedEvent?.Invoke(this, depositName); }public void AddDeposit(decimal amount, string depositName) { // Code to add deposit RaiseTransactionApprovedEvent?.Invoke(this, depositName); } -
Suscripción a eventos en la interfaz de usuario:
- Suscríbase al evento en el formulario principal para actualizar la lista de transacciones cada vez que se apruebe una nueva transacción.
public MainForm() { InitializeComponent(); account.RaiseTransactionApprovedEvent += Account_RaiseTransactionApprovedEvent; } private void Account_RaiseTransactionApprovedEvent(object sender, string e) { // Update the UI with the new transaction }public MainForm() { InitializeComponent(); account.RaiseTransactionApprovedEvent += Account_RaiseTransactionApprovedEvent; } private void Account_RaiseTransactionApprovedEvent(object sender, string e) { // Update the UI with the new transaction }
Event?.Invoke() Explicado
Tim Corey explica el uso de la sintaxis ?.Invoke() al lanzar eventos en C#. Este enfoque moderno simplifica el código y garantiza la seguridad de los hilos.
El operador de signo de interrogación
El signo de interrogación (?.) delante de Invoke es un operador de condición nula. Comprueba si el manejador de eventos es nulo antes de invocarlo, evitando posibles excepciones.
-
Enfoque tradicional:
- Antes, los desarrolladores utilizaban varias líneas de código para comprobar si el manejador de eventos era nulo y luego invocarlo.
if (RaiseTransactionApprovedEvent != null) { RaiseTransactionApprovedEvent(this, depositName); }if (RaiseTransactionApprovedEvent != null) { RaiseTransactionApprovedEvent(this, depositName); } -
Enfoque moderno con .Invoke():
- El operador null-conditional agiliza este proceso, realizando la comprobación de nulos e invocando el evento en una sola línea.
RaiseTransactionApprovedEvent?.Invoke(this, depositName);RaiseTransactionApprovedEvent?.Invoke(this, depositName);- Si
RaiseTransactionApprovedEventes nulo, la invocación no procede, evitando efectivamente cualquier excepción.
-
Beneficios:
- Simplifica el código: Reduce la cantidad de código necesario para invocar eventos de forma segura.
- Thread Safety: Elimina las condiciones de carrera mediante la comprobación de null y la invocación del evento en un solo paso.
Escuchar y escribir código para el evento
Tim explica cómo escuchar eventos personalizados en una aplicación Windows Forms y actualizar la interfaz de usuario en consecuencia.
-
Suscripción a eventos:
- Suscríbase al evento personalizado utilizando el operador +=.
customer.CheckingAccount.TransactionApprovedEvent += CheckingAccount_TransactionApprovedEvent;customer.CheckingAccount.TransactionApprovedEvent += CheckingAccount_TransactionApprovedEvent; -
Método de gestión de eventos:
- Definir un método para manejar el evento. Este método actualiza la interfaz de usuario en función de los datos del evento.
private void CheckingAccount_TransactionApprovedEvent(object sender, string e) { // Update the UI with the new transaction checkingTransactionsDataSource.DataSource = null; checkingTransactionsDataSource.DataSource = customer.CheckingAccount.Transactions; checkingBalanceLabel.Text = customer.CheckingAccount.Balance.ToString("C2"); }private void CheckingAccount_TransactionApprovedEvent(object sender, string e) { // Update the UI with the new transaction checkingTransactionsDataSource.DataSource = null; checkingTransactionsDataSource.DataSource = customer.CheckingAccount.Transactions; checkingBalanceLabel.Text = customer.CheckingAccount.Balance.ToString("C2"); }
Creación del evento personalizado: Evento en acción y recapitulación
Tim muestra en acción todo el proceso de creación, activación y gestión de eventos personalizados.
-
Desencadenante del evento:
- Lance el evento después de que se apruebe una transacción o cuando cambie el saldo.
private void OnTransactionApproved(string transactionName) { RaiseTransactionApprovedEvent?.Invoke(this, transactionName); }private void OnTransactionApproved(string transactionName) { RaiseTransactionApprovedEvent?.Invoke(this, transactionName); } -
Manejo de múltiples eventos:
- Asegúrese de que la aplicación escucha múltiples eventos, como transacciones y cambios de saldo, para mantener la interfaz de usuario actualizada en tiempo real.
public MainForm() { InitializeComponent(); customer.CheckingAccount.TransactionApprovedEvent += CheckingAccount_TransactionApprovedEvent; customer.SavingsAccount.TransactionApprovedEvent += SavingsAccount_TransactionApprovedEvent; } private void SavingsAccount_TransactionApprovedEvent(object sender, string e) { // Update the UI with the new savings transaction savingsTransactionsDataSource.DataSource = null; savingsTransactionsDataSource.DataSource = customer.SavingsAccount.Transactions; savingsBalanceLabel.Text = customer.SavingsAccount.Balance.ToString("C2"); }public MainForm() { InitializeComponent(); customer.CheckingAccount.TransactionApprovedEvent += CheckingAccount_TransactionApprovedEvent; customer.SavingsAccount.TransactionApprovedEvent += SavingsAccount_TransactionApprovedEvent; } private void SavingsAccount_TransactionApprovedEvent(object sender, string e) { // Update the UI with the new savings transaction savingsTransactionsDataSource.DataSource = null; savingsTransactionsDataSource.DataSource = customer.SavingsAccount.Transactions; savingsBalanceLabel.Text = customer.SavingsAccount.Balance.ToString("C2"); } -
Ejecución de la aplicación:
- Tim ejecuta la aplicación para demostrar cómo la interfaz de usuario se actualiza automáticamente en función de los eventos desencadenados por las transacciones.
Información sobre argumentos de eventos: Depuración
Tim muestra cómo depurar eventos e inspeccionar la información que se envía con ellos.
-
Cómo establecer un punto de interrupción:
- Establezca un punto de interrupción en el método del manejador de eventos para inspeccionar los datos del evento.
private void CheckingAccount_TransactionApprovedEvent(object sender, string e) { // Breakpoint here }private void CheckingAccount_TransactionApprovedEvent(object sender, string e) { // Breakpoint here } -
Depuración :
- Ejecute la aplicación y realice una transacción para activar el evento. Inspeccionar los argumentos de eventos en el depurador.
- El parámetro sender proporciona la instancia que ha generado el evento, y el parámetro e contiene los datos del evento.
Creación de otro evento personalizado (evento de sobregiro)
Tim Corey amplía la demostración creando otro evento personalizado para gestionar situaciones de descubierto. Este evento se activará cuando se produzca un descubierto y notificará al usuario el importe del mismo.
Definición del evento de sobregiro
Tim comienza definiendo un nuevo evento en la clase Cuenta para escenarios de sobregiro:
-
Declaración de eventos:
- Defina el evento utilizando la palabra clave event con un tipo decimal para pasar el importe del descubierto.
public event EventHandler<decimal> OverdraftEvent;public event EventHandler<decimal> OverdraftEvent; -
Desencadenante del evento:
- El evento se activa en la parte del código en la que se produce con éxito un descubierto.
if (overdraftSuccessful) { OverdraftEvent?.Invoke(this, overdraftAmount); }if (overdraftSuccessful) { OverdraftEvent?.Invoke(this, overdraftAmount); }
Suscripción al evento de sobregiro en el lado del salpicadero
-
Cableado del evento :
- Suscríbase al evento de sobregiro en el formulario del panel de control.
customer.CheckingAccount.OverdraftEvent += CheckingAccount_OverdraftEvent;customer.CheckingAccount.OverdraftEvent += CheckingAccount_OverdraftEvent; -
Gestión del evento:
- Defina un controlador de eventos para mostrar un mensaje cuando se produzca un descubierto.
private void CheckingAccount_OverdraftEvent(object sender, decimal e) { errorMessage.Text = $"You had an overdraft protection transfer of {e:C2}"; errorMessage.Visible = true; }private void CheckingAccount_OverdraftEvent(object sender, decimal e) { errorMessage.Text = $"You had an overdraft protection transfer of {e:C2}"; errorMessage.Visible = true; } -
Desencadenamiento y visualización del evento:
- Cuando se produce un descubierto, el evento se activa y actualiza la interfaz de usuario para notificárselo al usuario.
You had an overdraft protection transfer of $20.44
Escuchar el evento en varios lugares
Tim explica cómo escuchar el mismo evento en varios idiomas y formas, demostrando la versatilidad de los eventos.
-
Añadir una etiqueta a otro formulario:
- Añadir una etiqueta a un formulario secundario para mostrar mensajes de descubierto.
<asp:Label ID="errorMessage" runat="server" Visible="false" /><asp:Label ID="errorMessage" runat="server" Visible="false" />HTML -
Suscripción al evento:
- Suscríbase al evento de sobregiro en el formulario secundario.
customer.CheckingAccount.OverdraftEvent += SecondaryForm_OverdraftEvent;customer.CheckingAccount.OverdraftEvent += SecondaryForm_OverdraftEvent; -
Gestión del evento:
- Defina un controlador de eventos para mostrar el mensaje de descubierto en el formulario secundario.
private void SecondaryForm_OverdraftEvent(object sender, decimal e) { errorMessage.Visible = true; }private void SecondaryForm_OverdraftEvent(object sender, decimal e) { errorMessage.Visible = true; } -
Manejo simultáneo de eventos:
- Tim demuestra que el evento puede gestionarse de varias formas simultáneamente, lo que garantiza que todas las partes relevantes de la aplicación respondan al evento adecuadamente.
Both the main form and the secondary form display the overdraft message when the event is triggered.
Quitar de la memoria los receptores de eventos
Tim destaca la importancia de limpiar los escuchadores de eventos para evitar fugas de memoria y garantizar un rendimiento adecuado de la aplicación.
-
Desuscripción de eventos:
- Es crucial darse de baja de los eventos antes de destruir una instancia de clase o cerrar un formulario.
customer.CheckingAccount.OverdraftEvent -= CheckingAccount_OverdraftEvent;customer.CheckingAccount.OverdraftEvent -= CheckingAccount_OverdraftEvent;Por qué es importante:
- Si no se cancela la suscripción a eventos, pueden producirse fugas de memoria, ya que es posible que los objetos que escuchan los eventos no se recojan correctamente.
-
Uso de métodos con nombre:
- Evite el uso de funciones anónimas para los manejadores de eventos, ya que dificulta la cancelación de la suscripción a los eventos.
// Good practice: using named methods for event handlers// Good practice: using named methods for event handlers
Generic EventHandler: Pasando una Clase por T
Tim Corey explica las mejores prácticas para pasar datos a través de eventos, en particular las ventajas de utilizar una clase en lugar de tipos de datos simples como string o decimal.
Por qué usar una clase para datos de eventos
Tim comienza explicando por qué es menos habitual utilizar tipos de datos simples para los eventos y por qué suele ser mejor pasar una clase:
-
Flexibilidad y escalabilidad:
- El uso de una clase permite pasar varios datos relacionados a través de un evento. Si más adelante necesita añadir más datos, puede simplemente ampliar la clase sin cambiar la firma del evento.
-
herencia de EventArgs:
- Aunque antes era necesario que cualquier objeto que se pasara a través de un evento tuviera que heredar de EventArgs, esto ya no es así. Sin embargo, heredar de EventArgs puede ser beneficioso para la coherencia y la claridad.
Creación de la clase Overdraft EventArgs
Tim demuestra cómo crear una clase EventArgs personalizada para el evento de sobregiro.
-
Definir la clase:
- Cree una nueva clase que herede de EventArgs e incluya propiedades para los datos que desea pasar a través del evento.
public class OverdraftEventArgs : EventArgs { public decimal AmountOverdrafted { get; private set; } public string MoreInfo { get; private set; } public OverdraftEventArgs(decimal amountOverdrafted, string moreInfo) { AmountOverdrafted = amountOverdrafted; MoreInfo = moreInfo; } }public class OverdraftEventArgs : EventArgs { public decimal AmountOverdrafted { get; private set; } public string MoreInfo { get; private set; } public OverdraftEventArgs(decimal amountOverdrafted, string moreInfo) { AmountOverdrafted = amountOverdrafted; MoreInfo = moreInfo; } } -
Utilización de la clase en el evento:
- Actualice la declaración de eventos para utilizar la clase personalizada EventArgs.
public event EventHandler<OverdraftEventArgs> OverdraftEvent;public event EventHandler<OverdraftEventArgs> OverdraftEvent; -
Desencadenante del evento:
- Pase una instancia de la clase personalizada EventArgs al invocar el evento.
OverdraftEvent?.Invoke(this, new OverdraftEventArgs(amountNeeded, "Additional info"));OverdraftEvent?.Invoke(this, new OverdraftEventArgs(amountNeeded, "Additional info"));
Importancia de las propiedades de sólo lectura
Tim hace hincapié en la importancia de utilizar propiedades de sólo lectura en la clase EventArgs para evitar la modificación accidental de los datos de eventos.
-
Evitar modificaciones:
- Si las propiedades de la clase EventArgs tienen definidores públicos, cualquier controlador de eventos puede modificar los datos, lo que puede provocar un comportamiento inesperado.
- El uso de setters privados y la inicialización de propiedades a través del constructor garantizan la coherencia de los datos de eventos.
-
Ejemplo del problema:
- Tim demuestra cómo la modificación de los datos de un evento en un manejador de eventos puede afectar a otros manejadores si las propiedades no son de sólo lectura.
private void CheckingAccount_OverdraftEvent(object sender, OverdraftEventArgs e) { e.AmountOverdrafted = 1000; // This modification affects all handlers }private void CheckingAccount_OverdraftEvent(object sender, OverdraftEventArgs e) { e.AmountOverdrafted = 1000; // This modification affects all handlers } -
Solución:
- Utilice setters privados y pase datos a través del constructor para que las propiedades sean de sólo lectura.
public decimal AmountOverdrafted { get; private set; } public string MoreInfo { get; private set; }public decimal AmountOverdrafted { get; private set; } public string MoreInfo { get; private set; }
Excepción de cuándo usar Public Set (59:29)
Tim Corey destaca una importante excepción a la regla de utilizar definidores privados para las propiedades de datos de eventos. Esta excepción se da cuando es necesario permitir que los oyentes de eventos modifiquen los datos del evento, como en los casos en los que una transacción podría cancelarse en función de ciertas condiciones.
Ejemplo: Cancelación de una transacción
Tim ofrece un ejemplo en el que un controlador de eventos puede tener que cancelar una transacción. Esto se consigue añadiendo una propiedad CancelTransaction a la clase personalizada EventArgs.
-
Definición de la propiedad:
- Añade una propiedad pública con un getter y un setter a la clase EventArgs.
public class OverdraftEventArgs : EventArgs { public decimal AmountOverdrafted { get; private set; } public string MoreInfo { get; private set; } public bool CancelTransaction { get; set; } = false; public OverdraftEventArgs(decimal amountOverdrafted, string moreInfo) { AmountOverdrafted = amountOverdrafted; MoreInfo = moreInfo; } }public class OverdraftEventArgs : EventArgs { public decimal AmountOverdrafted { get; private set; } public string MoreInfo { get; private set; } public bool CancelTransaction { get; set; } = false; public OverdraftEventArgs(decimal amountOverdrafted, string moreInfo) { AmountOverdrafted = amountOverdrafted; MoreInfo = moreInfo; } } -
Configuración de la propiedad en el manejador de eventos:
- En el cuadro de mandos, el controlador de eventos puede establecer esta propiedad para cancelar la transacción.
private void CheckingAccount_OverdraftEvent(object sender, OverdraftEventArgs e) { if (denyOverdraft.Checked) { e.CancelTransaction = true; } errorMessage.Text = $"You had an overdraft protection transfer of {e.AmountOverdrafted:C2}"; errorMessage.Visible = true; }private void CheckingAccount_OverdraftEvent(object sender, OverdraftEventArgs e) { if (denyOverdraft.Checked) { e.CancelTransaction = true; } errorMessage.Text = $"You had an overdraft protection transfer of {e.AmountOverdrafted:C2}"; errorMessage.Visible = true; } -
Comprobación de la propiedad en el método fuente:
- En el método que desencadena el evento, compruebe si la propiedad CancelTransaction tiene el valor true antes de continuar.
if (args.CancelTransaction) { return false; // Transaction is canceled }if (args.CancelTransaction) { return false; // Transaction is canceled }
Hacer la aplicación más interactiva
Tim perfecciona la aplicación para hacerla más interactiva y fácil de usar.
-
Añadir una casilla de verificación para el control de sobregiros:
- Añada una casilla de verificación al formulario que permita al usuario activar o desactivar la protección contra sobregiros.
private void InitializeComponent() { this.denyOverdraft = new System.Windows.Forms.CheckBox(); // Initialize other controls this.denyOverdraft.Text = "Stop Overdrafts"; this.denyOverdraft.CheckedChanged += new System.EventHandler(this.denyOverdraft_CheckedChanged); }private void InitializeComponent() { this.denyOverdraft = new System.Windows.Forms.CheckBox(); // Initialize other controls this.denyOverdraft.Text = "Stop Overdrafts"; this.denyOverdraft.CheckedChanged += new System.EventHandler(this.denyOverdraft_CheckedChanged); } -
Manejo del estado de las casillas de verificación:
- En el controlador de eventos de la casilla de verificación, actualice la lógica para tener en cuenta el estado de la casilla de verificación cuando se decida cancelar una transacción.
private void denyOverdraft_CheckedChanged(object sender, EventArgs e) { if (denyOverdraft.Checked) { // Logic to stop overdraft transactions } }private void denyOverdraft_CheckedChanged(object sender, EventArgs e) { if (denyOverdraft.Checked) { // Logic to stop overdraft transactions } } -
Actualización del controlador de eventos:
- Asegúrese de que el controlador de eventos respeta el estado de la casilla de verificación para permitir o denegar los descubiertos.
private void CheckingAccount_OverdraftEvent(object sender, OverdraftEventArgs e) { if (denyOverdraft.Checked) { e.CancelTransaction = true; } errorMessage.Text = $"You had an overdraft protection transfer of {e.AmountOverdrafted:C2}"; errorMessage.Visible = true; }private void CheckingAccount_OverdraftEvent(object sender, OverdraftEventArgs e) { if (denyOverdraft.Checked) { e.CancelTransaction = true; } errorMessage.Text = $"You had an overdraft protection transfer of {e.AmountOverdrafted:C2}"; errorMessage.Visible = true; }
Resumen
Tim Corey concluye el tutorial resumiendo los puntos clave y las mejores prácticas para trabajar con eventos en C#.
-
Remover Event Listeners:
- Elimine siempre los escuchadores de eventos antes de destruir objetos para evitar fugas de memoria.
- Utilice el operador -= para darse de baja de los eventos.
customer.CheckingAccount.OverdraftEvent -= CheckingAccount_OverdraftEvent;customer.CheckingAccount.OverdraftEvent -= CheckingAccount_OverdraftEvent; -
Utilizar EventArgs herencia:
- Aunque no es obligatorio, heredar de EventArgs puede ser beneficioso para la coherencia y el uso de funciones integradas como EventArgs.Empty.
-
Configuradores privados para propiedades de sólo lectura:
- Utilice setters privados para evitar modificaciones no intencionadas en los datos de eventos. Permitir setters públicos sólo cuando sea necesario, como en el caso de las transacciones cancelables.
-
Sintaxis del manejador de eventos:
- Use el delegado EventHandler para definir eventos, proporcionando un patrón claro y consistente para pasar los datos del evento.
-
Operador de condición nula:
- Utilice el operador condicional nulo (?.Invoke()) para invocar eventos de forma segura sin arriesgarse a excepciones de referencia nula.
Conclusión
El completo tutorial de Tim Corey sobre eventos de C# proporciona información valiosa y ejemplos prácticos para crear, manejar y gestionar eventos de forma eficaz. Siguiendo estas buenas prácticas, los desarrolladores pueden crear aplicaciones más interactivas y con mayor capacidad de respuesta.
