C# - Usando expressões lambda
O
que são Expressões Lambda ? 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. |
As expressões lambda foram incluídas na plataforma .NET para dar suporte a consultas LINQ onde as cláusulas Where são assim compiladas como expressões lambdas.
Elas podem ser consideradas uma forma de delegate que pode passar ou retornar outra função.
|
Nota: Delegates permitem que uma classe use métodos de outra classe. Para saber mais sobre delegates leia o meu artigo: Usando Delegates
Assim, as expressões lambdas são funções ou rotinas, sem nome, que calculam e retornam um valor único; elas podem ser usadas em qualquer lugar que um tipo delegate for válido.
Na linguagem C# todas as expressões lambda usam o operador lambda =>, que é lido como "vai para".O lado esquerdo do operador lambda especifica os parâmetros de entrada (se houver) e o direito contém a expressão ou o bloco de instruções A expressão lambda x => x * x é lida assim : " x recebe x vezes x. " |
A sintaxe das expressões lambdas
A sintaxe de uma expressão lambda lembra a de uma função padrão. As diferenças são as seguintes:
- Uma expressão lambda não tem um
nome. - Expressões lambda não podem ter modificadores, como Overloads ou Overrides. - Expressões lambda não usam uma cláusula As para designar o tipo de retorno da função. Em vez disso, o tipo é inferido do valor que o corpo da expressão lambda avalia. Por exemplo, se o corpo da expressão lamba for Where cli.City = "Brazil", seu tipo de retorno é Boolean. - O corpo da função deve ser uma expressão, não uma instrução. O corpo pode consistir de uma chamada para um procedimento de função, mas não uma chamada para um procedimento sub. - Nas expressões lambadas não existe uma instrução Return. O valor retornado pela função é o valor da expressão no corpo da função. - Nas expressões lambdas não existe um instrução End Function. - Ou todos os parâmetros devem ter tipos de dados especificados ou todos devem ser inferidos. - Parâmetros opcionais e ParamArray não são permitidos. - Parâmetros genéricos não são permitidos. |
Nota: Com a evolução da plataforma .NET e os novos recursos que foram introduzidos a sintaxe das expressões lambdas foi simplificada, e desta forma você poderá encontrar a mesma função escrita de maneiras diferentes mas o resultado final será o mesmo.
Neste artigo vou ser bem prático e mostrar como podemos usar as expressões lambdas. Cabe a você analisando os exemplos adaptá-los às suas necessidades.
Eu vou procurar na maioria dos exemplos usar a sintaxe VB .NET.
Recursos usados:
Visual Basic 2010 Express Edition (E também o Visual C# 2010 Express Edition)
Usando e Abusando das expressões lambdas
1-) Neste primeiro exemplo temos uma lista de nomes e vamos usar as expressões lambdas para realizar as seguintes operações:
O código na linguagem VB .NET e o resultado são exibidos a seguir:
Module Module1 Sub Main() Dim lista As New List(Of String)() lista.Add("Jefferson") lista.Add("Jessica") lista.Add("Janice") lista.Add("Macoratti") lista.Add("Mario") lista.Add("Mario") lista.Add("Janice") lista.Add("Miriam") 'imprimir Console.WriteLine("Exibindo a lista Original") lista.ForEach(Function(s) ListarNoConsole(s)) Console.ReadKey() ' usar Distinct para eliminar os valores duplicados na lista lista = lista.Distinct().ToList() Console.WriteLine("Exibindo a lista após Distinct ") lista.ForEach(Function(s) ListarNoConsole(s)) Console.ReadKey() ' usar Sort para ordenar a lista lista.Sort() Console.WriteLine("Exibindo a lista após Distinct e com Sort") lista.ForEach(Function(s) ListarNoConsole(s)) Console.ReadKey() End Sub Function ListarNoConsole(ByVal nome As String) As String Console.WriteLine(nome) Return Nothing End Function End Module |
Note que foi preciso criar uma
função para poder listar os valores usando o método Se você não fazer isso vai
obter a mensagem de erro: Na versão C# mostrada abaixo funciona sem problemas: lista.ForEach(s => Console.WriteLine(s)); mas se você usar os conversores a expressão acima será convertida para: lista.ForEach(Function(s) Console.WriteLine(s)) não vai funcionar pois não retorna um valor. |
2-) Agora vamos listar algumas expressões lambdas comparando-as com a abordagem tradicional
Inicialmente vamos declarar alguns números inteiros:
Dim numeros As New List(Of Integer)(New Integer() {1, 9, 7, 4, 5, 6, 3, 8, 2, 10})
A seguir veremos alguns cenários, a utilização das expressões lambdas , a abordagem tradicional e o resultado:
Cenário | Usando Expressões lambdas |
Ordenação Ascendente |
For Each item In Numeros.OrderByDescending(Function(i)
i) Console.WriteLine(item) Next |
Verificar um
condição (verifica os números da lista são menores que 11) |
Dim resultado As Boolean = Numeros.All(Function(i) i < 11) |
Verificar um
condição (verifica um número da lista é igual a 5 ) |
Dim resultado As Boolean = Numeros.Any(Function(i) i = 5) |
Obter os 4
números do topo da Lista |
Dim subconjunto =
Numeros.Take(4) For Each item In subconjunto Console.WriteLine(item) Next |
Fazer a
ordenação ascendente, pegar os números menor que 8 e pegar os 5 números da lista |
Dim resultado = _ Numeros.OrderByDescending(Function(i) i).Where(Function(i) i < 8) .Take(5)
For Each item In resultado |
Localizando itens | Dim numero As String = Numeros.Find(Function(p) p = 6) |
Usando a abordagem tradicional | Resultado |
Numeros.Sort(Function(x As Integer, y As Integer) y.CompareTo(x)) | 1,2,3,4,5,6,7,8,9,10 |
Dim resultado As Boolean = True For Each i As Integer In Numeros If i >= 100 Then resultado = False End If Next |
True |
Dim resultado As Boolean = True For Each i As Integer In Numeros If i = 5 Then resultado = True End If Next |
True |
Dim subconjunto = New List(Of
Integer)() For i As Integer = 0 To 4 If i < Numeros.Count Then subconjunto.Add(i) End If Next |
1,9,7,4 |
Numeros.Sort(Function(x As Integer,
y As Integer) y.CompareTo(x)) Dim resultado As New List(Of Integer)() For Each i As Integer In Numeros If i < 8 Then If resultado.Count < 5 Then resultado.Add(i) End If End If Next |
7,6,5,4,3 |
For Each i As
Integer In Numeros If i = 6 Then console.Writeline(i) End If Next |
6 |
Com isso fizemos uma revisão de conceitos e mostramos como usar as expressões lambdas e percebemos que a sintaxe das expressões exige menos código.
"Em verdade , em verdade vos digo que vem a hora, e agora é, em que os mortos ouvirão a voz do Filho de Deus, e os que a ouvirem viverão."(João-5:25)
Referências: