Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Los eventos son, como los delegados, un mecanismo de enlace en tiempo de ejecución. De hecho, los eventos se crean con compatibilidad de lenguaje para los delegados.
Los eventos son una manera de que un objeto se difunda (a todos los componentes interesados del sistema) que ha ocurrido algo. Cualquier otro componente puede suscribirse al evento y recibir una notificación cuando se genere un evento.
Probablemente has usado eventos en alguno de tus desarrollos de software. Muchos sistemas gráficos tienen un modelo de eventos para notificar la interacción del usuario. Estos eventos notificarían el movimiento del mouse, las pulsaciones de botón y interacciones similares. Ese es uno de los más comunes, pero no es el único escenario donde se usan eventos.
Puede definir eventos que deben generarse para las clases. Una consideración importante al trabajar con eventos es que es posible que no haya ningún objeto registrado para un evento determinado. Debe escribir su código de manera que no se generen eventos cuando no haya escuchadores configurados.
La suscripción a un evento también crea un acoplamiento entre dos objetos (el origen del evento y el sumidero de eventos). Necesita asegurarse de que el receptor del evento cancela la suscripción del origen del evento cuando ya no está interesado en eventos.
Objetivos de diseño para la compatibilidad con eventos
El diseño del lenguaje para eventos tiene como destino estos objetivos:
- Permita un acoplamiento mínimo entre un origen de eventos y un receptor de eventos. Estos dos componentes pueden estar escritos por diferentes organizaciones e incluso se pueden actualizar según las distintas programaciones.
- Debe ser sencillo suscribirse a un evento y cancelar la suscripción de ese mismo evento.
- Las fuentes de eventos deben admitir varios suscriptores de eventos. También deben admitir no tener ningún suscriptor de eventos asociado.
Puede ver que los objetivos de los eventos son similares a los objetivos de los delegados. Es por eso que la compatibilidad con lenguaje de eventos se basa en la compatibilidad con el lenguaje delegado.
Soporte de idiomas para eventos
La sintaxis para definir eventos y darse de alta o de baja en eventos es una extensión de la sintaxis de los delegados.
Use la event
palabra clave para definir un evento:
public event EventHandler<FileFoundArgs>? FileFound;
El tipo del evento (EventHandler<FileListArgs>
en este ejemplo) debe ser un tipo delegado. Hay convenciones que debe seguir al declarar un evento. Normalmente, el tipo de delegado de eventos tiene un valor devuelto void. Las declaraciones de eventos deben ser un verbo o una frase verbal. Use el tiempo pasado cuando el evento notifica algo que ha ocurrido. Use un verbo tense presente (por ejemplo, Closing
) para notificar algo que está a punto de suceder. A menudo, el uso de la tense presente indica que la clase admite algún tipo de comportamiento de personalización. Uno de los escenarios más comunes es admitir la cancelación. Por ejemplo, un Closing
evento puede incluir un argumento que indicaría si la operación de cierre debe continuar o no. Otros escenarios permiten a los autores de llamadas modificar el comportamiento actualizando las propiedades de los argumentos de evento. Puede generar un evento para indicar una siguiente acción propuesta que realizará un algoritmo. El controlador de eventos puede exigir una acción diferente modificando las propiedades del argumento de evento.
Cuando quieras generar el evento, utiliza la sintaxis de invocación de delegado para llamar a los controladores de eventos.
FileFound?.Invoke(this, new FileFoundArgs(file));
Como se indica en la sección sobre delegados, el operador ?.
hace más fácil garantizar que no se intente generar el evento cuando no haya entidades abonadas a ese evento.
Se suscribe a un evento mediante el +=
operador :
var fileLister = new FileSearcher();
int filesFound = 0;
EventHandler<FileFoundArgs> onFileFound = (sender, eventArgs) =>
{
Console.WriteLine(eventArgs.FoundFile);
filesFound++;
};
fileLister.FileFound += onFileFound;
El método de controlador normalmente tiene el prefijo "On" seguido del nombre del evento, como se muestra en el código anterior.
Cancela la suscripción mediante el -=
operador :
fileLister.FileFound -= onFileFound;
Es importante declarar una variable local para la expresión que representa el controlador de eventos. Eso garantiza que la cancelación de la suscripción quita el controlador. Si, en su lugar, se ha utilizado el cuerpo de la expresión lambda, se está intentando eliminar un controlador que nunca ha estado asociado, lo que no da lugar a ninguna acción.
En el siguiente artículo, obtendrá más información sobre los patrones de eventos típicos y diferentes variaciones en este ejemplo.