C# Academy · Lesson

Compiling and Executing Expressions

Turn expression trees into runnable delegates.

Lesson 3 of 413 steps

Compiling and Executing Expressions is a free C# Academy lesson on CoddyKit. This is lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C# Academy learning path, and your progress syncs across the web and the CoddyKit app. The C# Academy course includes 4 lessons in total.

From Tree to Delegate

An expression tree is data until you compile it. Expression<TDelegate>.Compile() turns the tree into a real delegate you can invoke.

using System;
using System.Linq.Expressions;

Expression<Func<int, int>> tree = x => x + 1;
Func<int, int> fn = tree.Compile();
Console.WriteLine(fn(5)); // 6

Compiling a Hand-Built Tree

Trees you build manually compile the same way, producing a working delegate.

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)); // 12

Invoking the Result

The compiled delegate behaves like any other: call it, store it, pass it around.

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)); // 30

Compile Is Not Free

Compilation has a runtime cost, so cache the resulting delegate and reuse it instead of compiling on every call.

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();

Building Predicates Dynamically

A common use is building filter predicates at runtime from user input, then compiling to a 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)); // False

Combining Conditions

Use Expression.AndAlso / OrElse to combine predicates before compiling.

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 False

Compiling Calculations

You can assemble arithmetic formulas at runtime, useful for rule engines and calculators.

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)); // 120

DynamicInvoke for Untyped Lambdas

If you used a non-generic Expression.Lambda, compile to a Delegate and call 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)); // 15

Performance Note

A compiled expression runs at roughly delegate speed after the one-time compile. For hot paths, compile once at startup and store the delegate.

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 = 20

Errors Surface at Compile Time

If the tree is malformed (for example, missing a parameter), Compile() throws, so validate trees before relying on them.

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");
}

Putting It Together

Build, compile, and run a small formula in one flow.

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)); // 11

Quick Check

Confirm how to execute an expression tree.

Recap

You learned to compile and execute expression trees.

  • Compile() turns a tree into a callable delegate.
  • Cache the delegate; compilation has a one-time cost.
  • Build predicates and formulas dynamically, then compile.
  • Malformed trees throw at Compile().
Free to start

Learn C# with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
93
Lessons
346

Frequently Asked Questions

Is the “Compiling and Executing Expressions” lesson free?

Yes — the full text of “Compiling and Executing Expressions” is free to read here on the web. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C# Academy course, upgrade to CoddyKit PRO. The C# Academy course includes 4 lessons in total.

What will I learn in “Compiling and Executing Expressions”?

Turn expression trees into runnable delegates. You practise C# Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start C# Academy?

No prior experience is required. C# Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 3 of 4.

How long does the “Compiling and Executing Expressions” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this C# Academy lesson?

Yes. Every C# Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. What Are Expression Trees
  2. Building Expressions Manually
  3. Compiling and Executing Expressions
  4. Expression Trees in LINQ Providers
← Back to C# Academy