CodeBlanks Logo Icon CodeBlanks

Summary - Expression trees

C# course · Advanced · Lesson 42/83

Combine Expression and Compile to write a dynamic filter builder.

Summary - Expression trees

In this group you learned Expression<T>, lambda conversion, body inspection, Compile and IQueryable. You can convert a lambda to an expression tree, inspect it and turn it back into a delegate with Compile.

Now you will combine these to write a dynamic filter builder: first build an n > 10 expression tree by hand, then compile it and run it over an array.

Exercise Build a dynamic filter and invoke it

Build an n > 10 condition as an expression tree. Steps: ParameterExpression pe = Expression.Parameter(typeof(int), "n");, Expression body = Expression.GreaterThan(pe, Expression.Constant(10));, Expression<Func<int, bool>> filter = Expression.Lambda<Func<int, bool>>(body, pe);. Then build a delegate with Func<int, bool> fn = filter.Compile(); and print Console.WriteLine(fn(15));.

Show example solution
ParameterExpression pe = Expression.Parameter(typeof(int), "n"); Expression body = Expression.GreaterThan(pe, Expression.Constant(10)); Expression<Func<int, bool>> filter = Expression.Lambda<Func<int, bool>>(body, pe); Func<int, bool> fn = filter.Compile(); Console.WriteLine(fn(15));
Example solution:
using System;
using System.Linq.Expressions;

class Program
{
    static void Main()
    {
        ParameterExpression pe = Expression.Parameter(typeof(int), "n");
        Expression body = Expression.GreaterThan(pe, Expression.Constant(10));
        Expression<Func<int, bool>> filter = Expression.Lambda<Func<int, bool>>(body, pe);
        Func<int, bool> fn = filter.Compile();
        Console.WriteLine(fn(15));
    }
}

Exercise Apply the dynamic filter to an array

Build an n > 10 filter as an expression tree, produce a delegate with filter.Compile() and apply it to { 5, 12, 8, 20, 3 } with numbers.Where(fn). Iterate with foreach and print each element with Console.WriteLine(n).

Show example solution
ParameterExpression pe = Expression.Parameter(typeof(int), "n"); Expression body = Expression.GreaterThan(pe, Expression.Constant(10)); Expression<Func<int, bool>> filter = Expression.Lambda<Func<int, bool>>(body, pe); Func<int, bool> fn = filter.Compile(); var filtered = numbers.Where(fn); foreach (var n in filtered) { Console.WriteLine(n); }
Example solution:
using System;
using System.Linq;
using System.Linq.Expressions;

class Program
{
    static void Main()
    {
        int[] numbers = { 5, 12, 8, 20, 3 };
        ParameterExpression pe = Expression.Parameter(typeof(int), "n");
        Expression body = Expression.GreaterThan(pe, Expression.Constant(10));
        Expression<Func<int, bool>> filter = Expression.Lambda<Func<int, bool>>(body, pe);
        Func<int, bool> fn = filter.Compile();
        var filtered = numbers.Where(fn);
        foreach (var n in filtered)
        {
            Console.WriteLine(n);
        }
    }
}

Test yourself

  1. What does Compile return?

    • An expression tree
    • A runnable delegate
    • A Type object
    • A string
    Show answer

    A runnable delegate — Correct. Compile returns a runnable delegate.

  2. Match the property to its content

    Body
    Inner expression
    NodeType
    Operation kind
    Parameters
    Parameter list
    Compile
    Produces a delegate

All lessons in Advanced