ProgramaciónDesarrollador VB.NET

¿Cómo implementar el trabajo con eventos y delegados en Visual Basic y en qué se diferencia el escenario de uso para eventos estándar y personalizados?

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

En Visual Basic (VB.NET) delegados son un tipo que contiene una referencia a un método con una firma determinada, y sirven de base para el manejo de eventos. Eventos se construyen sobre delegados, permitiendo a los objetos notificar a otros sobre cambios ocurridos.

Para eventos estándar se utilizan delegados ya definidos, como EventHandler, mientras que para eventos personalizados se puede definir un delegado propio con la firma necesaria:

' Declaración de delegado y evento personalizado Public Delegate Sub ChangedEventHandler(sender As Object, e As EventArgs) Public Event Changed As ChangedEventHandler ' Uso del evento Public Sub OnChanged() RaiseEvent Changed(Me, EventArgs.Empty) End Sub

Puntos importantes:

  • Un evento solo se puede invocar dentro de la clase donde está declarado;
  • Los delegados se pueden combinar, creando una cadena de llamadas;
  • No respetar la firma correcta provoca errores de compilación.

Pregunta capciosa.

¿Por qué no se puede invocar un evento en Visual Basic fuera de la clase, incluso si está declarado como Public?

Respuesta: A pesar del modificador de acceso Public, un evento solo se puede "suscribir" o "cancelar suscripción" desde fuera de la clase, pero se puede invocar (RaiseEvent) solo dentro de la clase — esta es una especificidad del lenguaje que asegura encapsulamiento y control sobre la difusión de eventos. Por ejemplo:

Public Class Foo Public Event MyEvent() End Class Dim f As New Foo() ' No se puede hacer: f.RaiseEvent MyEvent() — el compilador no lo permitirá.

Ejemplos de errores reales debido a la falta de conocimiento sobre los puntos importantes del tema.


Historia

Proyecto Windows Forms: Un desarrollador intentó invocar el evento "DataUpdated" desde fuera de la clase de datos para actualizar la interfaz de usuario. No funcionó, el evento no se gestionó, tuvo que refactorizar la arquitectura y rehacer la lógica debido a una mala comprensión del alcance del evento.


Historia

Servicio web: Al declarar un delegado se omitió una variable en la firma. El evento se suscribió, pero se invocó con un error de tiempo de ejecución — el suscriptor esperaba un argumento, pero la llamada se hacía con dos.


Historia

Plugin para 1C: Los desarrolladores utilizaron FieldInfo.SetValue para simular la llamada a RaiseEvent. Esto causó una desincronización del estado de la interfaz y un fallo al actualizar la ensambladura.