C# día 13: indexadores, delegados, eventos
Hoy vamos a ver unos objetos y métodos algo especiales. Todo esta explicado en el código.
Por un lado, los indexadores
/** * Indexadores.cs * Los indexadores sirven para acceder a un array que puede haber dentro * de la clase de forma directa. Supongamos que tenemos un atributo que es un * array de nombres: protected string[] nombres; * Con el indexador o indexer accederiamos a ese array así: * MiClase clase = new MiClase(); * clase[0] = "Nuevo valor"; * Y para eso hay que definir un indexer. */ // Vamos a definir un equipo de fútbol public class Equipo { // Definimos un atributo que contiene los jugadores del equipo private string[] jugadores = new string[5]; // Un atributo para guardar el nombre del equipo private string nombreEquipo; // Constructor public Equipo(string nombre) { nombreEquipo = nombre; } // método que devuelve tamaño public int getSize() { return jugadores.Length; } // Indexador public string this[int indice] { get // Mediante el get podemos sacar un valor del array de jugadores { string temp; // Comprobamos indices no nos vayamos a salir if( indice >= 0 && indice <= 4 ) { temp = jugadores[indice]; } else { temp = ""; } return temp; } set // Mediante el set podemos establecer un valor en el array de jugadores { // Comprobamos los límites if( indice >= 0 && indice <= 4 ) { jugadores[indice] = value; } } } // Método principal public static void Main () { // Vamos a crear un gran equipo Equipo osasuna = new Equipo("C.A. Osasuna"); // Y ahora ya podemos establecer los nombre // de jugadores de forma directa osasuna[0] = "Ricardo"; osasuna[1] = "Krutxi"; osasuna[2] = "Josetxo"; osasuna[3] = "Iñaki Muñoz"; osasuna[4] = "Raúl García"; // Y ahora ya podemos recorrer el array for(int i = 0; i < osasuna.getSize(); i++) { System.Console.WriteLine("Jugador {0}", osasuna[i]); } } }Por otro los métodos delegados, similares a los de las interfaces
/** * Delegados.cs * Los métodos delegados son similares a los interfaces: definen * una forma de método (con su nombre, su return y sus parámetros) * pero sin implementación. */ using System; // Definimos la clase Aritmetica // que sirve para hacer operaciones simples public class Aritmetica { // Aquí definimos el método delegado // Que deberán implementar otras clases public delegate int Operacion(int a, int b); // Fijate en el parámetro public int HacerOperacion (Operacion op, int x, int y) { return (op(x, y)); } } public class UsarAritmetica { // Un método que implementa Operación public static int OperacionSumar(int a, int b) { return (a+b); } // Un método que implementa Operación public static int OperacionRestar(int a, int b) { return (a-b); } // Método principal public static void Main() { // ATENCION. Se crea una instancia del MÉTODO DELEGADO Aritmetica.Operacion sumar = new Aritmetica.Operacion(OperacionSumar); Aritmetica.Operacion restar = new Aritmetica.Operacion(OperacionRestar); // Y ahora creamos una instancia de la clase que contiene el delegado Aritmetica aritmetica = new Aritmetica(); // Y ahora usamos los métodos delegados int resultado = aritmetica.HacerOperacion(sumar, 665, 1); System.Console.WriteLine("Que fuerte, ha salido {0}", resultado); System.Console.WriteLine("Y ahora {0}", aritmetica.HacerOperacion(restar, 700, 34)); } }Vamos a ver, como implementar nuestros propios eventos. Es algo complejo, y hay que ir paso a paso
/** * Eventos.cs * Programas que muestran la definición y uso de Eventos. * Los eventos som situaciones en la ejecución de un programa * que pueden ser controlados para cambiar el comportamiento del mismo. * El ejemplo más claro es el entorno de ventanas: el evento de pinchar en un botón * puede provocar el cierre de una ventana. */ using System; // En esta caso vamos a crear un evento para controlar que el usuario // ha escrito la palabra viagra en la consola. El evento se va a disparar // cuando se asigne lo que se ha metido por pantalla a una variable: en ese // momento se comprobará si esa palabra es "viagra" y de ser así, avisará // Definimos el método delegado // Los parametros son: // 1. un objeto: el que genera el evento // 2. argumento del evento: una clase especifica para ese evento public delegate void capturaPalabraSpam(Object objeto, ArgumentoEvento e); // Definimos una clase para los argumentos del evento // que DEBE heredar de la clase: EventArgs public class ArgumentoEvento : EventArgs { public string palabra; // Constructor public ArgumentoEvento(string palabra) { this.palabra = palabra; } } // Ahora una clase para comprobar el evento public class CompruebaSpam { string palabraspam; public event capturaPalabraSpam EventoSpam; // Atencion cuando hagamos el set (la asignación) se disparará el evento! public string PalabraSpam { get { return palabraspam; } set { if ( EventoSpam != null) { ArgumentoEvento argumentos = new ArgumentoEvento(value); EventoSpam(this, argumentos); palabraspam = argumentos.palabra; } } } } public class PruebaEvento { // Handler: IMPLEMENTACION DEL MÉTODO DELEGADO // Definimos el handler para el evento static void detectaSpam(Object source, ArgumentoEvento e ) { if (e.palabra.ToLower() == "viagra") { System.Console.WriteLine("SPAM!!"); System.Console.WriteLine("Detectada palabra basura {0}",e.palabra); } } // Método principal public static void Main () { // creamos una instancia del comprobador CompruebaSpam comprueba = new CompruebaSpam(); // Le asignamos el handler de eventos que hemos implementado comprueba.EventoSpam += new capturaPalabraSpam(detectaSpam); System.Console.WriteLine("Vamos a ver si generamos un evento"); System.Console.WriteLine("Escribe algo, distinto de viagra, o no."); comprueba.PalabraSpam = System.Console.ReadLine(); } }