Delegados y Eventos en C#


después de mucho leer tutoriales de C#, inevitablemente me topé con conceptos como los delegados y los eventos.

Entender lo que son los eventos es fácil: son cualquier cosa que ocurre: como presionar un botón, la recepción de un dato vía internet o puerto serial, el inicio o fin de una descarga, etc.

Los delegados eran algo más confuso. Su definición dice que son punteros a funcioones, pero punteros "seguros", es decir: no accederán a espacios de la memoria RAM que no deberían (como los usados por el sistema operativo u otros programas). Y que en C# se usan principalmente para el manejo de eventos. Aún después de leerme estas definiciones no me quedaba claro qué eran o porqué existían hasta que en una pregunta que aventé a StackOverlocking que me costó un voto negativo (pero bien valió el precio) tuve que escribir un poco de código y finalmente pude entender su uso y manejo. 

Empecé con un formulario llamado "Form1" y un botón llamado "button1" creados con mi Visual Studio Express 2008. Lo que quise hacer era un programita que al hacer click izquierdo sobre el botón escribiera "Left" en el texto del formulario, y si se hace click derecho escribiera "Right". Así de simple, y también bastante tonto:

 

Para que el botón pudiera distinguir entre click derecho e izquierdo, creé la función MyMouseDouwn (con faltas de ortografía incluídas):


Si, en tiempo de diseño, se hace doble click sobre el botón se creará la siguiente función:

 

Ahora nos vamos al explorador de soluciones del Visual Studio y se hace doble click en el archivo Form.Designer.cs y expandir la región del código generado por el Diseñador de Windows Form. En este archivo, el Visual Studio coloca el código necesario para crear el formulario y el botón, así como el manejo de los eventos. Esto se hace mediante delegados, los cuales reciben una función para saber qué hacer cuando se dispara el evento.

 

Aquí la línea importante es this.button1.Click+=new System.EventHandler(this.button1_Click). Ésta se ejecuta al hacerle click al botón. Dado que llama a la función button1_Click, ejecutará el código que escribamos dentro de esta función. La palabra "this" se refiere a Form1. Se pone += para que los delegados acepten más de una ocurrencia de uno o más eventos.

Pero para este ejemplo, se debe borrar la función button1_Click y reemplazar a this.button1.Click+=new System.EventHandler(this.button1_Click) por este otro código:


No es necesario saberse esto de memoria, el Visual Studio escribe buena parte del código por nosotros. Basta saber cómo funciona. El nuevo delegado this.button1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.MyMouseDouwn) está recibiendo la función MyMouseDown y ejecutará el código correspondiente.