C# in Depth

Cover of C# in Depth
Order now (3rd edition)

Expression trees and parameters

Chapter 9: Lambda expressions and expression trees: 9.3.1

Created: 8/7/2008
Last updated: 8/8/2008

There was some confusion on the forum around why the expression shown in listing 9.6 doesn't have any parameters. After all, it performs addition on two numbers - doesn't that mean it has two parameters? Well, not quite...

Think of the expression as a black box - you don't know what goes on inside it. You just feed it some number of parameters, and it will give you a result (assuming it doesn't have a void return type, effectively). In this case the addition is always performed with 2 and 3 as the operands - nothing varies, so there are no parameters. That's why when we compile the expression tree in listing 9.7 we end up with a Func<int> - something which accepts no parameters but returns an integer.

An alternative way of thinking about this is as a method. Consider this code:

public static int Add2And3()
{
    return 2 + 3;
}

Again, it's adding 2 and 3 - but the method doesn't take any parameters.

If we want to create an expression tree which does take parameters, we need to change the code a bit. Here's the code to do that, courtesy of Marc Gravell:

// Declare the parameters
ParameterExpression firstParam = Expression.Parameter(typeof(int), "x");
ParameterExpression secondParam = Expression.Parameter(typeof(int), "y");

// Create an Expression that performs an operation on the parameters
Expression add = Expression.Add(firstParam, secondParam);
        
// Create an Expression<T> using Expression.Lambda
// Note that we specify the parameters again
Expression<Func<int,int,int>> lambda = 
    Expression.Lambda<Func<int,int,int>>(add, firstParam, secondParam);
        
// Compile the expression into a delegate
Func<int,int,int> compiled = lambda.Compile();
        
// Execute it
Console.WriteLine(compiled(2,3));

As you can see, this time when we call compiled we give it two parameters.

That may help to clear up some misunderstandings, but reader feedback has suggested that expression trees are best understood by just trying them. Write a small test program and play around. Have fun - and don't worry too much if you find expression trees tricky: if you understand the basic concept that they're expressing logic as data, and that you can create them using lambda expressions, that's as much as most developers will ever need to know.