1.06.2010

Entendiendo las Expresiones Lambda

Una de las características menos comprendidas de .NET son las expresiones Lambda. En este post voy a explicar lo más sencillo posible que son, y como funcionan.

Las expresiones lambda son un paso más para soportar programación funcional – aunque no son exclusivas de este paradigma – y a partir de C# 3.0 son consideradas el siguiente paso desde los delegates anónimos. Para comprender mejor como se llego a tener este concepto en C# 3.0 vamos a hacer un viaje en retrospectiva para ver como evolucionó este tema.

Inicialmente teniamos los delegates, los cuales en resumen me permitían pasar referencias a la función para poder ser invocadas por otra funcióna, en lenguaje C++ es un puntero a una función para poder ser utilizada como parámetro.

Por ejemplo, supongamos que queremos tener una función que imprima todos los número impares de un rango que el usuario le proporciona. Se podría crear una función que me indica que un número es impar o no de la siguiente forma:

public static bool EsImpar(int numero)
{
return (numero & 1) == 1;
}


Como queremos aplicarle la función a un grupo de números para determinar si son impares, podríamos crear un delegate – un puntero a una función – y acceder la función anterior como un parámetro. Inicialmente creamos un delegate con la signatura de la función esImpar, es decir con un parámetro int.



public delegate bool ProbarNumero(int numero);


Seguidamente procedemos a crear un método que nos imprima los números impares:



public static void ImprimirLosImpares(int inicio, int final, ProbarNumero prueba)
{
for (int i = inicio; i <= final; i++)
{
if (prueba(i))
Console.WriteLine(i);
}
}


Como podemos ver en este método, estamos pasando el delegate como parámetro para mandar a ejecutar una función la cual tiene como signatura un parámetro de tipo int. Este delegate va a apuntar a la función que yo le envíe por parámetro y la va a ejecutar en la sección del if. Seguidamente invocamos la función ImprimirLosImpares de la siguiente manera:



static void Main(string[] args)
{
ImprimirLosImpares(1, 15, EsImpar);
}



En esta ocasión, le pasamos como parámetro la función es impar, pero pudimos haber enviado como parámetro cualquier función que reciba un entero como parámetro. El resultado al ejecutar este código sería:



image



Esto me da independencia a la hora de invocar los métodos, por que yo podría tener una función imprimir, y varios métodos tales como EsPar, EsImpar, EsPrimo, etc. y utilizarlos cuando lo considere necesario.



En C# 2.0 este concepto de los delegates se extendió con el uso de los métodos anónimos. Los métodos anónimos me permiten eliminar la necesidad de tener que declarar el método y escribirlo en línea. Todo lo que escribimos antes en C#, podemos resumirlo en este método anónimo:



static void Main(string[] args)
{
ImprimirLosImpares(1, 15,
delegate(int numero)
{
return (numero & 1) == 1;
}
);
//ImprimirLosImpares(1, 15, EsImpar);
}


En este caso, en lugar de pasarle el puntero al método, le pasamos un método anónimo directamente como parámetro para que se ejecute dentro de ImprimirLosPares. El resultado al ejecutar este bloque de código es el mismo que el resultado anterior.



Las expresiones lambda son una sintaxis más compacta de lo anterior. Nosotros podemos en C# 3.0+ escribir la funcionalidad anterior simplemente con el siguiente código:



static void Main(string[] args)
{
ImprimirLosImpares(1, 15, numero => (numero & 1) == 1);
}



Las expresiones lamba son siempre de la forma:



parametros => expresión



por lo que en la función anterior, pasamos la variable número como parámetro y luego le aplicamos la condición para definir si es impar o no.



Technorati Tags: ,

1 comentario:

Anónimo dijo...

Más claro no podía estar.. gracias por el aporte