Linq to Objects - Parte 2
Click here to read this post in English
Olá a todos. Vou dar continuidade ao post anterior sobre Linq to Objects e mostrar algumas outras funcionalidades desta tecnologia que eu tenho achado tão legal. Espero que vocês também achem legal à medidade que eu vou mostrando as coisas que eu tenho visto e estudado. Vamos nessa!
Nos posts anteriores eu mostrei a sintaxe de query do Linq, mas há uma outra forma de fazer consultas com Linq. Todas as instruções (até mais algumas) que usamos nas queries Linq podem ser representada por chamadas de métodos das classes de coleções. Vamos fazer uma consulta na nossa lista do outro post:var Meses = new List<string> {
"Janeiro",
"Fevereiro",
"Março",
"Abril",
"Maio",
"Junho",
"Julho",
"Agosto",
"Setembro",
"Outubro",
"Novembro",
"Dezembro"
};
var MesesComJ =
Meses
.Where(mes => mes.StartsWith("J"))
.OrderByDescending(mes => mes)
.Select(mes => mes);
foreach (var m in MesesComJ) {
Console.WriteLine(m);
}
Esta forma, na minha opinião, não é tão legal quanto a outra, mas com certeza também é legal e também mostra de forma clara o que o código quer recuperar.
Para listas simples o select é opcional, mas apenas na forma de métodos - na sintaxe de query é obrigatório.
Hey, que operador maluco é aquele ali? Qual, o =>? Ele é o operador usado para Lambda Expressions. Ah, legal... Mas o que são Lambda Expressions?
Alguns métodos de objetos aceitam como argumento uma definição de função em vez de um valor fixo. Vamos rever o caso do .Where:.Where(mes => mes.StartsWith("J"))
Vale lembrar que este é um único parâmetro que está sendo passsado para o método. Quando a função fizer a iteração completa na lista ela vai usar este parâmetro para decidir se o item que está na dada posição vai retornar na lista resultante ou não.
Para isso nós definimos a função ali, na hora, criando a condição de retorno de registro. Mas para criar o filtro nós precisamos do contexto. É aí que entra o operador "goes to" (vai para). Ele serve para indicar qual é o contexto da função que estamos criando. Esta condição vai ser testada para cada item da lista (mes.StartsWith("J")), onde mes é o elemento corrente da lista, ou seja: para cada linha da iteração mes será o item corrente. Este tipo de expressão é comum em linguagens funcionais. Vale lembrar que o nome da variável antes do operador é definida por nós, e o código do outro lado deve usar o mesmo nome.
Há muitas expressões de query em Linq; e mesmo que eu soubesse todas este post seria quilométrico! Vamos aqui ver mais dois interessantes: Skip e Take.
Em C# não há representação para Skip e Take na sintaxe de query, somente em métodos. O Skip serve para "pular" resultados e o Take para "pegar" um certo número de linhas:var Meses456 =
Meses
.Skip(3)
.Take(3);
O resultado será:Abril
Maio
Junho
A chamada e a ordem dos métodos já nos diz o que a consulta vai retornar: "Pule 3 itens e pegue 3".
Dá para combinar a linguagem de query e as expressões também:var MesesCom5Letras = (
from mes in Meses
where mes.Length == 5
orderby mes descending
select mes)
.Skip(1)
.Take(2);
O resultado será:Junho
Julho
À medida em que eu vou aprendendo coisas novas eu posto aqui para o pessoal do Estação. Até treinem e postem aqui suas experiências também. Um grande abraço e até a próxima.