23.9.06

Delegados, Eventos y Métodos anónimos

Introducción: Implementando una interfaz gráfica con windows forms, teniendo un MDI principal y un par de formularios hijos, vi la necesidad que en un momento dado, un formulario hijo realice algo que el padre tiene que interceptar, y tomar cartas en el asunto. En este caso necesitaba setear la propiedad Text del MDI, a partir de alguna acción de un formulario hijo; algo sencillo.

En C# y sin la posibilidad de usar algo análogo al namespace My, que posee la gente de VB.Net, tuve que recurrir a un Eventos y Delegados,...y ya que estamos...Métodos anónimos.

En VB.Net, estando en formulario hijo con el namespace my seria algo bastante tonto:

My.Forms.MDIMain.Text = nombredeltitulo

En C# me las arregle con un mecanismo que permita que el padre (MDI principal) se quede a la "escucha" de un evento, y así iniciar acciones, pero con información que le provee el hijo. Es decir:

  • Los metodos a ejecutar: son del MDI principal
  • Y la información necesaria -los parametros- : provienen del form hijo.

Ahora bien, como se podrían implementar estos tres conceptos juntos para resolver esto ?

Ahora pasemos a un ejemplo donde se vé una interacción entre los objetos:

using System;

// Declaracion del delegado

public delegate void EventHandler(string str);

public class Program
{
public static void Main()
{
TestHandler tb
= new TestHandler();

//Tres maneras de hacer lo mismo

//1- asignacion comun

tb.Evento += new EventHandler(MetodoStringToUpper);

//2- asignacion por inferencia de tipos
tb.Evento += MetodoStringToLower;

//3- asignacion con metodo anonimo

tb.Evento += delegate(string str)
{
string otrostring =
String.Format(
"Metodo Anonimo: {0}",str);
Console.WriteLine(otrostring);
};
tb.Disparar();

Console.ReadLine();
}

public static void MetodoStringToUpper(string str)
{
Console.WriteLine(str.ToUpper());
}

public static void MetodoStringToLower(string str)
{
Console.WriteLine(str.ToLower());
}
}


class TestHandler
{
//Evento de tipo EventHandler
public event EventHandler Evento;


public void Disparar()
{
string mystring = "Dario.Net";

//Disparo el evento, con un string de parámetro

Evento(mystring);
}
}

Primeramente declararemos un delegado: EventHandler, que podrá apuntar a metodos que contengan como argumentos el tipo string y que no retornen valores (void).

Luego en la clase TestHandler se declara un evento: Evento, del tipo EventHandler (nuestro delegado).

Y la funcion: Disparar(); se encargará de disparar el evento con un string como argumento: mystring="Dario.Net".

Vayamos al Main().

Instanciamos un objeto del tipo TestHandler, con el operador += y vamos agregando al evento, todos los métodos que queremos que se ejecuten, uno tras otro.

Luego invocamos a Disparar(). y se invocan, en este orden los tres métodos: MetodoStringToUpper,MetodoStringToLower y el querido metodo anónimo.

Cosas a notar:

El que dispara el evento es el TestHandler, y le pasa un parámetro: mystring.

Los métodos están en el Main, pero esos métodos se ejecutarán por el hijo...cosa loca no ?

El método anonimo: es como si fuera un metodo más, pero definido en el momento de su uso, e inline (buenísimo!)

Bien, ahora que vimos el ejemplo (y espero que lo hayan entendido), imaginemos algo: hagamos de cuenta que Program es el Main, y TestHandler es el Form1. Y podemos solucionar facilmente el problema que plantee al comienzo...y muchos más!

Para profundizar les recomiendo este artículo.

Saludos y dejen comentarios.

17.9.06

Developer Day

Ayer, 16 de agosto de 2006 se realizaron las jornadas de desarrollo en la UTN - Facultad Regional Resistencia - Chaco, donde se dieron lugar a interesantes charlas:

  • Web Semántica - Por César Acuña
  • Programación en SQL Server 2000 y 2005 - Por Mariano Minoli
  • Lo Nuevo de Visual Basic 2005 - Por Vanina Geneiro y Diego Poza
  • Layering y ORM: Un caso real - Por Dario Quintana
  • LINQ - Por Orlando Canteros y Guillermo Ruffino
  • Web Services - Por Agustín Casiva y Marcos Ibañez

En dichas jornadas estuve compartiendo un tema: Desarrollo en capas y Object/Relational Mapping. Donde se mostró un aplicación real que implementaba estos patrones. La verdad, me gustó mucho dar la charla. Hasta después se mostró algo de db4o también, para poder ejemplificar mejor sobre diferencias entre bases de datos relacionales y orientadas a objetos.

Y despues Orlando y Guillermo hablaron sobre LINQ, la verdad que está demasiado bueno el tema...y no veo la hora que salga la versión final de este proyecto para empezar a usarlo en serio.