C# - Apresentando Expression Trees - III


  No artigo de hoje vou apresentar o conceito de Expression Trees na linguagem C#.

Continuando o artigo anterior vamos criar e usar uma Expression Tree.

Até o momento sabemos que Expression ou Expression<T> são classes que podem representar código C# como dados, e, que diferentemente de Func<> ou Action<> as Expressions são dados compilados sobre o código, sendo que a maioria dos provedores da LINQ foram criados usando Expressions.

Vamos então criar uma Expression e explorá-la para entender melhor o processo.

Vamos partir de um delegate Func<> que realiza a concatenação de strings definido a seguir:

Func<string, string, string> JuntaStrings = (str1, str2) => string.Concat(str1, str2);

Como eu quero explorar e analizar a expressão acima, tenho que tratar o código como dados e para isso vou criar uma Expression, que como já vimos vai nos dar o código abaixo:

Expression<Func<string, string, string>> JuntaStringsExpr = (str1,str2) => string.Concat(str1,str2);

Vamos analisar essa Expression levando em conta a estrutura de uma Expression(body,parameters,nodetype e type):

 

Assim a expressão é analizada como uma árvore com NodeType,Left, Right, Body, etc. O que significa que ela pode ser escrita assim:

Parameters (Left) -> (Root) NodeType -> (Right)Body


Agora temos os dados, para que possamos realizar operações com base em seus valores. É assim que a Linq To SQL e Linq to Entities funcionam. As Expressions são analizadas e convertidas em instruções SQL preparando a consulta.

Vamos agora executar a expressão.

Ao contrário de Func<> e Action<> as Expressions não são compiladas de imediato pois elas precisam ser compilados antes de executar a instrução subjacente, assim, para executar a nossa Expressão, devemos primeiro compilá-la.(como já vimos).

var funcaoCompilada = JuntaStringsExpr.Compile ();
var resultado = funcaoCompilada("Jose Carlos ", "Macoratti");

Ou você pode escrever em uma única instrução como:

var resultado = JuntaStringsExpr.Compile()("Jose Carlos", "Macoratti");

Dessa forma, usamos uma Expression para representar um Lambda e seu corpo, analisamos os detalhes de como isso é representado como uma Expression Tree e vimos como compilar e invocar o código representado pela árvore de expressões.

O código completo pode ser visto abaixo:

E com isso concluímos a apresentação desse importante recurso que são as Expressions e Expression Trees.

Bem-aventurados os limpos de coração, porque eles verão a Deus;
Bem-aventurados os pacificadores, porque eles serão chamados filhos de Deus;
Mateus 5:8,9

Referências:


José Carlos Macoratti