viernes, 30 de mayo de 2014

Delegados en C# - Parte 2: Métodos Anónimos

Tabla de Contenido

0. Introducción
1. ¿Qué es un Método Anónimo?
1.1 Declaración
1.2 Ejemplos
1.2.1 Uso de un método anónimo
1.2.2 Método anónimo inmerso en otro método anónimo
1.2.3 Métodos anónimos para eventos de componentes visuales
1.2.4 Métodos anónimos en hilos de ejecución
2. Alcance de Parámetros
3. Conclusiones
4. Glosario
5. Literatura & Enlaces

0. Introducción

En esta segunda parte vamos a dar un recorrido por las principales ideas de los métodos anónimos. Veremos su concepto, uso, y utilidad. Entenderemos que se tratan de soluciones ad-hoc para atacar problemas que requieren de una solución heurística. Introduciré varios ejemplos parar facilitar su comprensión, y desde luego, su inherente utilidad.

1. ¿Qué es un Método Anónimo?

A diferencia de los métodos formales, es decir, aquellos que poseen una declaración (sea de instancia o estática) junto con un nombre que los identifica inequívocamente. Los métodos anónimos carecen de esta particularidad, es decir, no poseen un nombre; lo anterior no los aisla de la posesión de un conjunto de parámetros, y un tipo de retorno.

1.1 Declaración

Para declarar un método anónimo utilizamos esta sintaxis (versión abstracta):

delegate({parámetros})
{
  // implementación
}

Un ejemplo particular, podría ser:

// Definición de delegado:
public delegate void Delegado(int x);

// Creación de delegado con un método anónimo:
Delegado del = delegate(int x)
{
Console.WriteLine("Valor de `x`: {0}", x.ToString());
}

1.2 Ejemplos

1.2.1 Uso de un método anónimo

Recurramos al siguiente ejemplo (ejecutable) de demostración de delegados y métodos anónimos:


En la línea 6 declaramos un método anónimo con tipo de retorno void y un parámetro de tipo int. La nueva construcción (método anónimo), ocurre en las líneas 14 a 17. Veamos que estamos instanciado de manera implícita un delegado, esto lo determina el código:

delegate(int valor)
{
Console.WriteLine("El contenido de `valor` es: {0}", valor.ToString());
};

Ya en la línea 23 se invoca (implícitamente) el método anónimo con el valor 99 como argumento.

> Prueba de ejecución.

Resultado:


El contenido de `valor` es: 99

Captura:
Resultado ejemplo básico de métodos anónimos con delegados
Figura 1. Resultado ejemplo básico de métodos anónimos con delegados.

1.2.2 Método anónimo inmerso en otro método anónimo

Otra de las posibilidad que nos brinda el lenguaje C# es la de poder definir un método anónimo dentro de otro. En el siguiente ejemplo vamos a demostrar esta potencialidad del lenguaje:

Archivo MetodoAnonimoInmerso.cs:



En las líneas 8, 11 se declaran los delegados DelegadoExterior, y DelegadoInterior. Ambos métodos poseen la siguiente firma:

  • Retorno: void
  • Parámetros: «ninguno»

Más adelante, en las líneas 27-27 se declara el método anónimo para una variable de tipo DelegadoExterior, y en el interior una variable de tipo DelegadoOInterior con su respectivo método anónimo.

> Prueba de ejecución.

Resultado:
Resultado ejemplo de método anónimo dentro de otro
Figura 2. Resultado ejemplo de método anónimo dentro de otro.

En la Figura 2 se muestra el resultado de una prueba en local.

1.2.3 Métodos anónimos para eventos de componentes visuales

Los métodos anónimos también pueden usarse para declarar la implementación de respuesta eventos de interacción de componentes visuales por parte del usuario.

btnCalcular.Click += delegate(object o, EventArgs e)
{
MessageBox.Show("Calculando...");
// Resto de la implementación del evento.
}

1.2.4 Métodos anónimos en hilos de ejecución

Veamos cómo es posible declarar un método anónimo para la implementación de un hilo (thread) en C#:

public void IniciarThread()
{
Thread hilo1 = new Thread(
delegate()
{
Console.WriteLine("Blog ");
Console.WriteLine("xCSw");
};
);

hilo1.Start();
}

Lo anterior gracias a la compatibilidad del constructor de la clase Thread [5](N:System.Threading) con firma [6]:

public Thread(ThreadStart start)

2. Alcance de Parámetros

Hemos visto que un método anónimo puede tanto contener parámetros (ejemplos secciones 1.2.1, 1.2.2, y 1.2.4) como no (ejemplo sección 1.2.3), a esto es necesario agregar que los parámetros definidos para un método anónimo a través de un delegado son de alcance de bloque, es decir, sólo dentro del cuerpo de declaración del método anónimo.

En [2] nos advierten que intentar utilizar sentencias de salto goto, greak, y continue dentro del método anónimo. Igualmentemente ocurre al intentar hacer saltos desde el exterior del método anónimo.

Por otro lado, en una declaración de código fuente como esta:

int n = 0;

Delegado del = delegate()
{
Console.WriteLine("Captura de `n`: {0}", ++n.ToString());
};

la variable n es capturada por el método anónima, además, el ciclo de vida de n está determinado hasta la existencia que demarque el recolector de basura (cfr. Gestión de Memoria en C# y Liberación de Recursos y Finalizadores en C#).

Otro punto a considerar es que los métodos anónimos no pueden contener parámetros con los modificadores ref y/o out (cfr. Variables y Parámetros en C#).

3. Conclusiones

Exploramos las características de los métodos anónimos usando delegados en C#. Los ejemplos que vimos nos demostraron su utilidad a convertirse en soluciones simplificadas de un método formal (método con nombre). Al final vimos las restricciones de uso de variables, modificadores (out, y ref) en los elementos definidos dentro y fuera de un método anónimo.

4. Glosario

  • Alcance
  • Delegado
  • Delegate
  • Método anónimo
  • out
  • Parámetro
  • ref

5. Literatura & Enlaces

[1]: Visual C# 2010 Recipes by Allen Jones and Adam Freeman. Copyright 2010 Allen Jones and Adam Freeman, 978-1-4302-2525-6.
[2]: Anonymous Methods (C# Programming Guide) - http://msdn.microsoft.com/en-us/library/0yw3tz5k.aspx
[3]: C#: Coding With Anonymous Methods, Iterators, And Partial Classes - http://msdn.microsoft.com/en-us/magazine/cc163970.aspx
[4]: Anonymous Methods in C# - http://www.c-sharpcorner.com/UploadFile/dacca2/anonymous-method-in-C-Sharp/
[5]: Thread Class (System.Threading) - http://msdn.microsoft.com/en-us/library/System.Threading.Thread(v=vs.110).aspx
[6]: Thread Constructor (ThreadStart) (System.Threading) - http://msdn.microsoft.com/en-us/library/xx3ezzs2(v=vs.110).aspx
[7]: Gestión de Memoria en C# - http://ortizol.blogspot.com/2013/06/gestion-de-memoria-en-c.html
[8]: Liberación de Recursos y Finalizadores en C# - http://ortizol.blogspot.com/2013/10/liberacion-de-recursos-y-finalizadores.html
[9]: Variables y Parámetros en C# - Parte 2 - http://ortizol.blogspot.com/2013/09/variables-y-parametros-en-c-parte-2.html


J

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.