# Delegación y Eventos
## Programando con delegados

Otra cuestión a tener en cuenta cuando programemos con delegados, es que éstos no tienen en cuenta la visibilidad de los métodos. Esto permite llamar a métodos privados desde otros si ambos tienen acceso al delegado. Es decir, imaginemos que una clase guarda en un delegado referencia a uno de sus métodos privados. Si desde otra clase que tenga acceso al delegado (pero no al método privado) se convoca a éste, se ejecutará ese método. En verdad no se está violando la privacidad del método, porque no es la clase quien lo convoca, sino el delegado, que sí tiene acceso al mismo.

### Llamadas a múltiples métodos

Hasta el momento hemos visto como hacer que un delegado guarde referencia de un sólo método. Sin embargo, existe una clase, System.MulticastDelegate, que deriva de System.Delegate, que se diferencia de esta última en que puede tener múltiples métodos en su lista de invocaciones. Al usar la palabra clave "delegate" se están usando estas clases de forma interna, sin tener que hacer referencia a ellas en el código.
Para poder hacer esto usaremos los operadores sobrecargados '+=' y '-=' que, respectivamente, añaden o eliminan a un método de la lista de invocaciones de un delegado.
Para intentar asimilar esto mejor, veámoslo con un ejemplo más completo.

### Ejemplo de uso de delegados

Podemos ver que, en este caso, nuestro delegado sólo manipula métodos que no devuelvan nada y que reciban como único parámetro una cadena. Si observamos los métodos que componen ClaseA y ClaseB, el denominado MetodoNoValido no concuerda con la definición de nuestro delegado, ya que recibe un entero y no una cadena. Eso implica que no vamos a poder llamarlo desde ninguna instancia del delegado que hemos declarado. Sin embargo, con las otras no tendremos ningún problema.
Bien, observemos paso a paso lo que hace el programa. Fijemos nuestra atención en el método principal (Main). Primero insertamos un método estático. Como sabemos, para llamar a un método de este tipo, se hace a partir del nombre de la clase y no de una instancia. Bien, hasta aquí nada que no hayamos visto ya, pero ahora insertemos un segundo módulo en el delegado.
Como hemos dicho, hemos usado el operador '+=' para incluir otro método más en nuestro delegado, en este caso MetodoPublico. Si usaramos de nuevo el operador '=', borraríamos la antigua lista de invocaciones y crearíamos una nueva con sólo una función referenciada. Ahora tenemos dos métodos en la lista de invocaciones de nuestro delegado. Por último, creamos una instancia de ClaseB, la cual en su constructor incluye una referencia más al delegado, en este caso a MetodoPrivado.
Si ahora compilamos y ejecutamos este código, obtendremos esto:
ClaseA.MetodoEstatico ha sido llamado: Hola mundo
ClaseA.MetodoPublico ha sido llamado: Hola mundo
ClaseB.MetodoPrivado ha sido llamado: Hola mundo
Como vemos, aunque hemos convocado al delegado desde la clase Ejemplo, que no tiene acceso a MetodoPrivado, éste ha sido ejecutado. Como explicamos, esto es así porque realmente quien lo está haciendo es el delegado y no el método Main.
Por último, una cuestión más. Hasta el momento hemos visto a delegados que gestionan miembros que no devuelven ningún valor. Pero, ¿qué ocurre cuando los devuelven? En este caso, la ejecución del delegado no devuelve todos esos valores, sólo el que retorne el último método de su lista de invocación.