Академический Документы
Профессиональный Документы
Культура Документы
Una vez que tenemos unas nociones de que son los eventos y qu relacin tienen con los delegados, es hora de que veamos de forma prctica cmo definirlos en nuestras clases y qu es lo que tenemos que hacer para que una aplicacin lo intercepte, sin olvidarnos de cmo y cundo lo podemos producir. Tambin nos ocuparemos de ver cmo eliminar un mtodo de la lista de mtodos que deben ser notificados por el evento.
Nota: Segn las recomendaciones de nomenclatura de .NET Framework, los nombres de los delegados deben terminar con EventHandler.
Nota: De forma interna y totalmente transparente para nosotros, el compilador de C# crea un objeto, (el cual inicialmente tiene un valor nulo), que ser el encargado de gestionar los clientes que interceptan los eventos. Para lograrlo, define dos mtodos pblicos llamados add_NombreDelEvento y remove_NombreDelEvento que son los que se utilizan cuando aadimos nuevos mtodos a la lista de mtodos a notificar y cuando los quitamos de dicha lista.
Para que no se produzca ese error, lo que debemos hacer es comprobar si el "evento" contiene un valor nulo, y en caso de que no lo tenga lanzamos el evento:
if (DatosCambiados != null) DatosCambiados();
Nota: Segn las recomendaciones de .NET Framework sobre los eventos, para lanzar un evento en una clase deberamos declarar un mtodo protegido llamado OnNombreDelEvento, al que llamaremos cuando tengamos que lanzarlo. Y si alguna clase se deriva de la nuestra y sobrescribe dicho mtodo para adaptarlo a sus necesidades, debera llamar a ese mtodo de la clase base para que los delegados que existan sigan notificando dicho evento.
Antes de asociar el evento con un mtodo, debemos declararlo con la misma firma que ha definido el delegado:
static void emp_DatosCambiados() { Console.WriteLine("Datos cambiados en el Empleado"); }
En este caso, es un mtodo de tipo void que no recibe ningn argumento. Por ltimo tendremos que "ligar" el evento con el mtodo, esto lo hacemos de la siguiente forma:
Obtendremos la siguiente salida en la consola: Ruiz, pepe Datos cambiados en el Empleado Ruiz, Jose Ya que al asignarle un valor a la propiedad es cuando se lanza el evento.
Veamos el cdigo completo de la clase Empleado, para ver cundo lanzamos los eventos:
public class Empleado { private string nombre; private string apellidos; private decimal salario;
public Empleado(string nombre, string apellidos, decimal salario) { this.nombre = nombre; this.apellidos = apellidos; this.salario = salario; }
public string Apellidos { get{ return apellidos; } set { apellidos = value; if (DatosCambiados != null) DatosCambiados(); } }
Desasociar eventos
Cuando no queramos que un evento sea interceptado, podemos eliminar el delegado que previamente hemos asociado. Esto lo haremos de la misma forma que cuando asociamos un mtodo a un evento, pero en lugar de utilizar el operador +=, tendremos que usar el operador -=. En el siguiente cdigo "desligamos" el mtodo del evento, de forma que a partir de esa asignacin, dejar de recibir notificaciones:
emp.DatosCambiados -= new DatosCambiadosEventHandler(emp_DatosCambiados);
No se mostrar la lnea que indica que los datos del empleado han cambiado.
Si aplicamos esta nueva forma de definir un evento en nuestra clase Empleado, debemos eliminar la declaracin que tenamos del evento y utilizar esta otra:
// La variable privada ser la que se usar // en esta clase para lanzar los eventos. private DatosCambiadosEventHandler datosCambiados;
// El evento declarado al estilo de una propiedad. public event DatosCambiadosEventHandler DatosCambiados { add { datosCambiados += value; Console.WriteLine("El mtodo a notificar es: {0}", value.Method.Name); Console.WriteLine("Se aade un delegado al evento DatosCambiados"); } remove { datosCambiados -= value; Console.WriteLine("Se elimina un delegado al evento DatosCambiados"); } }
Lo primero que hacemos es declarar una variable privada del mismo tipo que el delegado, esa variable ser la que se use, como solemos hacer con cualquier propiedad, para almacenar "el valor interno de la propiedad", aunque en este caso sea una propiedad "especial". Despus declaramos el evento-propiedad, que como vemos se hace de la misma forma que cuando declaramos un evento, con la diferencia de que en lugar de terminarlo con un punto y coma, utilizamos un bloque de cdigo, en el que definimos otros dos bloques, pero en lugar de utilizar los tpicos get y set de las propiedades normales, aadiremos un bloque para cuando se aada el delegado (add) y otro para cuando se elimine (remove). Esos dos bloque reciben un parmetro implcito (value), el cual representa al delegado que se quiere aadir o quitar, por tanto debemos realizar esas mismas operaciones dentro de cada bloque, utilizando los operadores += y -=. Como podemos comprobar en el listado anterior, tambin podemos aadir ms cdigo a cada bloque, incluso podemos obtener informacin del delegado usado para asociar el evento con un mtodo. Para producir este evento, en lugar de usar el declarado como propiedad, tendremos que usar la variable privada, el uso es exactamente el mismo que vimos anteriormente:
nombre = value; if (datosCambiados != null)
datosCambiados();
Aunque parezca que es el mismo cdigo de antes, debemos recordar que C# hace distincin entre maysculas y minsculas. En el programa que utiliza la clase Empleado no tenemos que hacer ningn cambio, ya que la forma que implementemos nuestro evento no afecta fuera de la clase.