C# - Apresentando
o tipo Expression
![]() |
No artigo de hoje vou mostrar como definir e como invocar uma Expression. |
Nós já aprendemos (veja as referências no final do artigo) que uma expressão lambda pode ser atribuída aos delegates do tipo Func ou Action para processar as coleções na memória.
O compilador .NET converte a expressão lambda atribuída ao delegate Func ou Action em código executável em tempo de compilação.
A LINQ introduziu um novo Tipo denominado Expression que representa uma expressão lambda fortemente tipada. Assim, agora uma expressão lambda também pode ser atribuída ao tipo Expression<TDelegate>.
O compilador .NET
converte a expressão lambda que é atribuída ao tipo
Expression<TDelegate> em uma Expression tree
em vez de um código executável.
Essa Expression tree ou árvore de expressão é usada
pelos provedores de consulta LINQ remotos como uma estrutura de dados para criar
uma consulta de tempo de execução a partir dela (como LINQ-to-SQL,
EntityFramework ou qualquer outro provedor de consulta LINQ que implemente a
interface IQueryable <T>).
Veja na figura abaixo as diferenças quando a expressão lambda é atribuída ao delegado Func ou Action e quando é atribuída ao tipo Expression no LINQ:
Vamos ver então como definir e invocar uma Expression.
Criando uma Expression
Vamos criar um projeto do tipo Console Application no VS 2017 Community.
No projeto Console crie uma classe chamada Aluno com o código abaixo:
Vamos incluir o namespace System.Linq.Expressions no projeto para podermos criar uma Expression.
Para criar uma Expression temos que usar a classe Expression<TDelegate> e vamos precisar criar um delegate do tipo Func ou Action.
Vamos então definir um delegate Func para usar na Expression :
Func<Aluno, bool> isMaiorDeIdade =
a => a.Idade > 21 && a.Idade < 20;
Agora basta criar a Expression:
Expression<Func<Aluno, bool>> isMaiorDeIdade_Ex = a => a.Idade > 21 && a.Idade < 20;
Assim convertemos o delegate Func em uma Expression apenas envolvendo o delegate na Expression.
Abaixo temos o código completo do arquivo Program.cs :
Podemos fazer a mesma coisa usando um delegate Action.
Expression <Action<Aluno>> ImprimirNomeAluno = a => Console.WriteLine(a.Nome);
Lembrando que Action não retorna valor.
Invocando uma Expression
Podemos invocar o delegate envolto por uma Expression da mesma maneira que um delegate normal, mas antes temos que compilar o delegate usando o método Compile() que vai retornar um delegate do tipo Func ou Action que poderá ser invocado.
Assim primeiro vamos compilar o delegate Func:
Func<Aluno, bool> isMaiorDeIdade = isMaiorDeIdade_Ex.Compile();
A seguir vamos invocar a Expression e exibir o resultado:
bool resultado =
isMaiorDeIdade(new Aluno() { AlunoId = 1,Nome = "Maria",Idade = 51 });
Console.WriteLine($"O aluno é maior de idade ? {resultado} ");
A seguir temos o código completo do arquivo Program.cs :
Vimos então que quando uma expressão lambda é atribuida a uma variável, campo ou parâmetro cujo tipo é Expression<TDelegate> o compilador emite instruções para construir uma Expression Tree.
Na próxima parte do artigo veremos o que é são as Expression Trees.
Pegue o
projeto aqui :
CExpressions.zip
"Combati o bom combate, acabei a carreira,
guardei a fé.
Desde agora, a coroa da justiça me está guardada, a qual o Senhor, justo juiz,
me dará naquele dia;
e não somente a mim, mas também a todos os que amarem a sua vinda. "
2
Timóteo 4:7,8
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Super DVD C# - Recursos de aprendizagens e vídeo aulas para C#
Curso Fundamentos da Programação Orientada a Objetos com VB .NET
C# - Delegates - Macoratti
C# - Apresentando o delegate Func - Macoratti
C# - Usando expressões lambdas para os delegates Predicate, Func
Usando expressões lambdas para implementar delegates - Macoratti
C# - Compreendendo delegates - II (revisitado) - Macoratti
C# - Usando delegates para chamar operações matemáticas - Macoratti