Compilando e executando expressões
Transforme árvores de expressão em delegados executáveis.
Compilando e executando expressões é uma aula grátis de C# Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C# Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C# Academy inclui 4 aulas no total.
Da árvore ao delegado
Uma árvore de expressões é apenas dados até que você a compile. Expression<TDelegate>.Compile() transforma a árvore em um delegado real que você pode invocar.
using System;
using System.Linq.Expressions;
Expression<Func<int, int>> tree = x => x + 1;
Func<int, int> fn = tree.Compile();
Console.WriteLine(fn(5)); // 6Compilando uma árvore construída manualmente
As árvores que você constrói manualmente são compiladas da mesma forma, produzindo um delegado funcional.
using System;
using System.Linq.Expressions;
var x = Expression.Parameter(typeof(int), "x");
var body = Expression.Multiply(x, Expression.Constant(3));
var lambda = Expression.Lambda<Func<int, int>>(body, x);
var fn = lambda.Compile();
Console.WriteLine(fn(4)); // 12Invocando o resultado
O delegado compilado se comporta como qualquer outro: você pode chamá-lo, armazená-lo e passá-lo adiante.
using System;
using System.Linq.Expressions;
Expression<Func<int, int, int>> addExpr = (a, b) => a + b;
var add = addExpr.Compile();
Console.WriteLine(add(2, 3)); // 5
Console.WriteLine(add(10, 20)); // 30Compile não é gratuito
A compilação tem um custo em tempo de execução; portanto, armazene o delegado resultante em cache e reutilize-o, em vez de compilá-lo a cada chamada.
using System;
using System.Linq.Expressions;
Expression<Func<int, int>> tree = x => x * x;
var square = tree.Compile(); // compile once
for (int i = 1; i <= 3; i++)
Console.Write(square(i) + " "); // 1 4 9
Console.WriteLine();Construindo predicados dinamicamente
Um uso comum é construir predicados de filtragem em tempo de execução a partir da entrada do usuário e, em seguida, compilá-los em um Func.
using System;
using System.Linq.Expressions;
var n = Expression.Parameter(typeof(int), "n");
var isPositive = Expression.GreaterThan(n, Expression.Constant(0));
var pred = Expression.Lambda<Func<int, bool>>(isPositive, n).Compile();
Console.WriteLine(pred(5)); // True
Console.WriteLine(pred(-2)); // FalseCombinando condições
Use Expression.AndAlso / OrElse para combinar predicados antes de compilá-los.
using System;
using System.Linq.Expressions;
var n = Expression.Parameter(typeof(int), "n");
var inRange = Expression.AndAlso(
Expression.GreaterThanOrEqual(n, Expression.Constant(1)),
Expression.LessThanOrEqual(n, Expression.Constant(10)));
var fn = Expression.Lambda<Func<int, bool>>(inRange, n).Compile();
Console.WriteLine(fn(5) + " " + fn(11)); // True FalseCompilando cálculos
Você pode montar fórmulas aritméticas em tempo de execução, o que é útil para mecanismos de regras e calculadoras.
using System;
using System.Linq.Expressions;
var p = Expression.Parameter(typeof(double), "p");
// price * 1.2 (add 20% tax)
var withTax = Expression.Multiply(p, Expression.Constant(1.2));
var calc = Expression.Lambda<Func<double, double>>(withTax, p).Compile();
Console.WriteLine(calc(100)); // 120DynamicInvoke para lambdas sem tipo
Se você usou uma Expression.Lambda não genérica, compile-a em um Delegate e chame DynamicInvoke.
using System;
using System.Linq.Expressions;
var x = Expression.Parameter(typeof(int), "x");
var body = Expression.Add(x, Expression.Constant(10));
Delegate d = Expression.Lambda(body, x).Compile();
Console.WriteLine(d.DynamicInvoke(5)); // 15Observação sobre desempenho
Uma expressão compilada é executada aproximadamente à velocidade de um delegado após a compilação inicial. Para caminhos críticos, compile uma vez na inicialização e armazene o delegado.
using System;
using System.Linq.Expressions;
Expression<Func<int, int>> tree = x => x + x;
var doubler = tree.Compile();
int total = 0;
for (int i = 0; i < 5; i++) total += doubler(i);
Console.WriteLine(total); // 0+2+4+6+8 = 20Os erros aparecem durante a compilação
Se a árvore estiver malformada (por exemplo, com um parâmetro ausente), Compile() gera uma exceção; portanto, valide as árvores antes de depender delas.
using System;
using System.Linq.Expressions;
var x = Expression.Parameter(typeof(int), "x");
var y = Expression.Parameter(typeof(int), "y");
try {
// body references y but lambda only declares x
var lambda = Expression.Lambda<Func<int, int>>(Expression.Add(x, y), x);
lambda.Compile();
} catch (InvalidOperationException) {
Console.WriteLine("unbound parameter");
}Reunindo tudo
Construa, compile e execute uma pequena fórmula em um único fluxo.
using System;
using System.Linq.Expressions;
var x = Expression.Parameter(typeof(int), "x");
var formula = Expression.Add(
Expression.Multiply(x, Expression.Constant(2)),
Expression.Constant(3)); // 2x + 3
var fn = Expression.Lambda<Func<int, int>>(formula, x).Compile();
Console.WriteLine(fn(4)); // 11Verificação rápida
Confirme como executar uma árvore de expressões.
Recapitulação
Você aprendeu a compilar e executar árvores de expressões.
Compile()transforma uma árvore em um delegado chamável.- Armazene o delegado em cache; a compilação tem um custo único.
- Construa predicados e fórmulas dinamicamente e compile-os em seguida.
- Árvores malformadas geram uma exceção em
Compile().
Perguntas Frequentes
A aula “Compilando e executando expressões” é grátis?
Sim — o texto completo de “Compilando e executando expressões” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C# Academy, atualize para CoddyKit PRO. O curso de C# Academy inclui 4 aulas no total.
O que vou aprender em “Compilando e executando expressões”?
Transforme árvores de expressão em delegados executáveis. Você pratica C# Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar C# Academy?
Nenhuma experiência prévia é necessária. C# Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Compilando e executando expressões”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de C# Academy?
Sim. Cada aula de C# Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- O que são árvores de expressão
- Construindo expressões manualmente
- Compilando e executando expressões
- Árvores de expressão em provedores LINQ