.NET - Usando Expressões Lambdas


As expressões lambdas são funções que podem conter expressões e declarações que são usadas para criar delegates e árvores de expressões onde o tipo das variáveis não precisam ser declarados visto que elas usam métodos anônimos.

Uma expressão lambda é uma função anônima que você pode usar para criar delegados ou tipos de árvore de expressão. Usando expressões lambda, você pode gravar funções locais que podem ser passadas como argumentos ou serem retornadas como o valor de chamadas de função. Expressões lambda são particularmente úteis para escrever expressões de consulta LINQ. http://msdn.microsoft.com/pt-br/library/vstudio/bb397687.aspx

Como uma expressão lambda é uma expressão, ela somente pode ser usada como parte de uma instrução. Desta forma podemos declarar a expressão lambda e chamar a função passando um valor ao parâmetro:

y => y * y   
    Function(y) y * y   
Na linguagem C# todas as expressões usam o operador lambada => que significa "vá para"
C# VB .NET  

O lado esquerdo do operador lambda especifica os parâmetros de entrada (se houver) e o lado direito trata a expressão ou bloco de instruções.

Exemplo:

Dim lambda1 As Func(Of Integer, Integer) = Function(x) x * x

Esta expressão lambda cria o Delegate Func que vai receber um valor do tipo Integer e devolver como resultado um valor do tipo Integer.

O código completo onde atribuímos um valor para o cálculo da expressão é dado a seguir:

   Sub Main()

        Dim expLambda1 As Func(Of Integer, Integer) = Function(x) x * x
        Console.WriteLine("Valor de 5 * 5 = " + expLambda1(5).ToString())
        Console.ReadKey()

    End Sub

Como uma expressão lambda é uma expressão ela somente pode ser usada como parte de uma instrução. Desta forma podemos declarar a expressão lambda e chamar a função passando um valor ao parâmetro.

Obs: O tipo delagate Func definido no namespace System possui 16 sobrecargas (overloads).

Func(Of T, TResult) - é um delegate que aceita um parâmetro integer e retorna um Boolean. Assim podemos usar :

  Dim IsPar As Func(Of Integer, Boolean) = Function(n) n Mod 2 = 0
  Console.WriteLine(IIf(IsPar(20), "É um número Par", "Não é um número Par"))
  Console.ReadKey()

Assim uma expressão lambda é uma versão ainda mais condensada de um método anônimo.

Usando expressões lambdas para definir funções matemáticas

As expressões lambda são basicamente de dois tipos:

Creio que nada mais claro que mostrar exemplos de utilização de expressões lambdas na definição de funções matemáticas.

A seguir temos as diversas formas de usar as expressões lambdas:

1- Implicitamente

        Dim func1 As Func(Of Integer, Integer) = Function(a) a + 1
        Console.WriteLine("func1(4)={0}", func1(4))
        Console.WriteLine("func1.Invoke(4)={0}", func1.Invoke(4))   
        Console.ReadKey()
            Func<int, int> func1 = a => a + 1;
            Console.WriteLine("func1(4)={0}", func1(4));
            Console.WriteLine("func1.Invoke(4)={0}", func1.Invoke(4));
            Console.ReadKey();
VB.NET C#

O resultado da execução defina uma função do tipo y = x+1 é visto a seguir:

2- Com um corpo de instrução

       Dim func2 As Func(Of Integer, Integer) = Function(a)
                                                                       Return a + 1
                                                                    End Function
        Console.WriteLine("func2(4)={0}", func2(4))
        Console.WriteLine("func2.Invoke(4)={0}", func2.Invoke(4))   
        Console.ReadKey()
            Func<int, int> func2 = a => { return a + 1; };
            Console.WriteLine("func1(4)={0}", func1(4));
            Console.WriteLine("func1.Invoke(4)={0}", func1.Invoke(4));
            Console.ReadKey();
VB.NET C#

O mesmo resultado é obtido pelo código acima escrito de forma diferente.

3- Usar parâmetros formais no corpo da instrução

        Dim func3 As Func(Of Integer, Integer) = Function(a As Integer) a + 1
        Console.WriteLine("func3(4)={0}", func3(4))
        Console.WriteLine("func3.Invoke(4)={0}", func3.Invoke(4))   
        Console.ReadKey()
            Func<int, int> func3 =(int a) => a + 1;
            Console.WriteLine("func3(4)={0}", func3(4));
            Console.WriteLine("func3.Invoke(4)={0}", func3.Invoke(4));
            Console.ReadKey();
VB.NET C#

O mesmo resultado é obtido agora usando parâmetros formais no corpo da instrução.

4- Usar parâmetros com o corpo da instrução

       Dim func4 As Func(Of Integer, Integer) = Function(a as Integer) 
                                                                       Return a + 1
                                                                    End Function
        Console.WriteLine("func4(4)={0}", func4(4))
        Console.WriteLine("func4.Invoke(4)={0}", func4.Invoke(4))   
        Console.ReadKey()
           Func<int, int> func4 = (int a)  => { return a + 1; };
            Console.WriteLine("func4(4)={0}", func4(4));
            Console.WriteLine("func4.Invoke(4)={0}", func4.Invoke(4));
            Console.ReadKey();
VB.NET C#

5- Usar um método de expressão delegate

        Dim func5 As Func(Of Integer, Integer) = Function(a As Integer) a + 1
        Console.WriteLine("func5(5)={0}", func5(5))
        Console.WriteLine("func5.Invoke(5)={0}", func5.Invoke(5))
        Console.ReadKey()
            Func<int, int> func5 = delegate(int a) { return a + 1; };
            Console.WriteLine("func5(4)={0}", func5(4));
            Console.WriteLine("func5.Invoke(4)={0}", func5.Invoke(4));
            Console.ReadKey();
;
VB.NET C#

O mesmo resultado agora usando um Delegate.

6- Usar Múltiplos parâmetros

a- Soma algébrica

   Dim func7 As Func(Of Integer, Integer, Integer, Integer) = 
Function(a, b, c) (a + b + c + 1) 
   Console.WriteLine("func7(3,4,5)={0}" & vbLf, func7(3, 4, 5))
   Console.WriteLine("func7.Invoke(3,4,5)={0}" & vbLf, func7.Invoke(3, 4, 5))
   Console.ReadKey()     
   Func<int, int, int, int> func7 = (a, b, c) => (a + b + c + 1);
   Console.WriteLine("func7(3,4,5)={0}\n", func7(3,4,5));
   Console.WriteLine("func7.Invoke(3,4,5)={0}\n", func7.Invoke(3,4,5));
   Console.ReadKey();
VB.NET C#

Aqui temos a definição de uma soma algébrica do tipo : y = a+b+c+1

b- Cálculo do discriminante

     Dim Discriminante As Func(Of Double, Double, Double, Double) = 
Function(a, b, c) (b * b - 4 * a * c)
     Console.WriteLine("Discriminante de 3x^2+12x+5 é {0}", Discriminante(3, 12, 5))
     Console.ReadKey()
  Func<double, double, double, double> Discriminante = (a, b, c) => 
(b * b - 4 * a * c);
  Console.WriteLine("Discriminante de 3x^2+12x+5 é {0}" , Discriminante(3,12,5));
  Console.ReadKey();
VB.NET C#

Nesta expressão lambda estamos calculando o discriminante de uma equação quadrática : 3x^2+12x+5

Lembre-se que a fórmula do discriminante é : b^2 - 4ac

c- Fatorial(n)

        Dim Fatorial As Func(Of Integer, Integer) = Nothing
        Fatorial = Function(n) If(n <= 1, 1, n * Fatorial(n - 1))
        Console.WriteLine("Resultado de {0}! = {1}" & vbLf, 10, Fatorial(10))    
        Console.ReadKey()
            Func<int, int> Fatorial = null;
            Fatorial = (n) =>  n <= 1 ? 1 : n * Fatorial (n-1);
            Console.WriteLine("Resultado de {0}! = {1}\n", 10, Fatorial(10)); 
            Console.ReadKey();
VB.NET C#

Aqui temos o cálculo do fatorial de um número. No exemplo calculamos 10 ! (lê-se 10 fatorial)

d- Números de Fibonacci

        Dim Fibonacci As Func(Of Integer, Integer) = Nothing
        Fibonacci = Function(n) If(n > 1, Fibonacci(n - 1) + Fibonacci(n - 2), n)  
        Console.WriteLine("Fibonacci({0}) = {1}" & vbLf, 10, Fibonacci(10))
        Console.ReadKey()
            Func<int, int> Fibonacci = null;
            Fibonacci = (n) => n > 1 ? Fibonacci(n-1) + Fibonacci(n-2) : n ;
            Console.WriteLine("Fibonacci({0}) = {1}\n", 10, Fibonacci(10));
            Console.ReadKey();
VB.NET C#

Neste código obtemos o décimo número de Fibonacci.

e- Números Primos

   Dim Primos As Func(Of Integer, Integer, Boolean) = Nothing
   Primos = Function(x, y) If((y = 1), True, (If(x Mod y = 0, False, Primos(x, y - 1))))  
   Dim isPrimo As Func(Of Integer, Boolean) = Function(x) Primos(x, x / 2)
   Console.WriteLine("{0} {1} é um número primo", 13, (If(isPrimo(13), "", " Não ")))         
   Console.ReadKey()
  Func<int, int, bool> Primos = null;
  Primos = (x,y) => ( y == 1 ) ? true : ( x % y == 0 ? false : Primos(x,y-1));
  Func<int, bool> isPrimo = x => Primos(x, x / 2);
  Console.WriteLine("{0} {1} é um número primo", 13, (isPrimo(13) ? "" : " Não "));
  Console.ReadKey();
VB.NET C#

Nesta expressão lambda verificamos se um número é primo. No exemplo verificamos o número 13.

Pegue o projeto completo aqui: ExpressoesLambdasCSharp.zip e ExpressoesLambdasVBNET.zip

1Pe 2:13 Sujeitai-vos a toda autoridade humana por amor do Senhor, quer ao rei, como soberano,
1Pe 2:14 quer aos governadores, como por ele enviados para castigo dos malfeitores, e para louvor dos que fazem o bem.

Referências:


José Carlos Macoratti