Utilizando LINQ to Objetcs em Delphi Prism
Durante os últimos 10 anos as linguagens, frameworks e plataformas de desenvolvimento tiveram inúmeras evoluções, todos nós sabemos estas foram para melhor, mas em especial uma eu considero como uma das maiores inovações dos últimos 10 anos e se chama LINQ.
LINQ é um conjunto de extensões para o .NET Framework que abrange operações de consulta integrada à linguagem, definição e transformação. Através de qualquer linguagem para .NET você pode efetuar consultas através de bibliotecas de classes para tirar proveito desses recursos.
Existem várias formas de utilização do LINQ, consultando objetos, XML e banco de dados, já existem outras implementações que permitem efetuar consulta em outros artefatos.
Para começar a entender, vou exemplificar a utilização de LINQ consultando uma lista de objetos, mais conhecido como LINQ to Objects.
O código fonte dos exemplos aqui utilizando se encontram no diretório de exemplos do Delphi Prism, pasta Linq, estes foram desenvolvidos por mim mesmo e incorporados ao produto.
Veja a classe abaixo, esta contém um Array of String, imagine a situação onde você deseja filtrar estes dados, ordenar de diversas formas e o retorno ser uma classe. Isso é o que podemos fazer com LINQ.
type Words = public class private words : Array of String := ['hello', 'Delphi Prism', 'wonderful', 'linq', 'beautiful', 'world' ]; public method SimpleSelect; method ComplexSelect; end;
Abaixo temos a implementação do método SimpleSelect, onde utilizamos LINQ para trazer uma lista com as palavras que tenham menos de 5 caracteres.
implementation method Words.SimpleSelect; begin var shortwords := From word in words Where word.Length <= 5 Select word; Console.WriteLine('Simple select statment'); Console.WriteLine; for each word in shortwords do begin Console.WriteLine(word); end; end;
Vamos passo a passo neste código, primeira parte.
var shortwords := From word in words Where word.Length <= 5 Select word; end;
Desta forma temos uma coleção chamada shortwords, cria dinâmicamente e que podemos agora percorrer e apresentar os resultados da seguinte forma.
for each word in shortwords do begin Console.WriteLine(word); end;
Até aqui você se pergunta se é possível ordenar, agrupar, etc. A resposta é simples, sim é possível. Abaixo um exemplo onde retornamos as palavras agrupadas por tamanho, em ordem descendente e gerando o retorno como uma classe e não apenas uma string.
var groups := From word in words Order by word asc Group word by word.Length into lengthGroups Order by lengthGroups.Key desc select new class (Length:=lengthGroups.Key,Words:=lengthGroups);
Foi adicionado as cláusulas Order by e Group, onde Key é o tamanho da string para cada item da coleção.
Agora uma das coisas mais interessantes é a criação dinâmica das classes através da sintaxe new class, além disso a utilização de expressões lambida onde eu defino a propriedade e valor a ser atribuído dinamicamente, exemplo abaixo Length:=lengthGroups.Key .
select new class (Length:=lengthGroups.Key,Words:=lengthGroups);
Caso você deseja imprimir o conteúdo agrupado, basta percorrer a variável groups, onde a propriedade Words representa a lista de palavras para cada grupo.
for each grupo in groups do begin Console.WriteLine('Words of length ' + grupo.Length); for each word in grupo.Words do Console.WriteLine(' ' + word); end;
Próximo post falarei sobre LINQ to XML, aguardem.
Para qual versão do Delphi LINQ to Object pode ser usado ? Tem mais exemplos de como aplicar e em quais situações. Eu não conheço.