Generating Dynamic Methods with Expression Trees in Visual Studio 2010

Expression trees first appeared in Visual Studio 2008, where they were mainly used by LINQ providers. You can use expression trees to represent code in a tree-like format, where each node is an expression. You can also convert expression trees into compiled code and run it. This transformation enables dynamic modification of executable code as well as the execution of LINQ queries in various databases and the creation of dynamic queries. Expression trees in Visual Studio 2008 are explained in Charlie Calvert’s blog post Expression Tree Basics.

In this post I’m going to show how expression trees were extended in Visual Studio 2010 and how you can use them to generate dynamic methods (a problem that previously could be solved only by emitting MSIL). But although I strongly recommend reading Charlie’s blog post first, I still need to repeat some basics to spell out certain nuances.

Creating Expression Trees

The easiest way to generate an expression tree is to create an instance of the Expression<T> type, where T is a delegate type, and assign a lambda expression to this instance. Let’s take a look at the code.

// Creating an expression tree by providing a lambda expression.

Expression<Action<int>> printExpr = (arg) => Console.WriteLine(arg);

// Compiling and invoking the expression tree.

printExpr.Compile()(10);

// Prints 10.

In this example, the C# compiler generates the expression tree from the provided lambda expression. Note that if you use Action<int> instead of Expression<Action<int>> as a type of the printExpr object, no expression tree will be created, because delegates are not converted into expression trees.

However, this is not the only way to create an expression tree. You can also use classes and methods from the System.LINQ.Expressions namespace. For example, you can create the same expression tree by using the following code.

// Creating a parameter for the expression tree.

ParameterExpression param = Expression.Parameter(typeof(int), "arg");

// Creating an expression for the method call and specifying its parameter.

MethodCallExpression methodCall = Expression.Call(

typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) }),

param

);

// Compiling and invoking the methodCall expression.

Expression.Lambda<Action<int>>(

methodCall,

new ParameterExpression[] { param }

).Compile()(10);

// Also prints 10.

Of course this looks much more complicated, but this is what actually happens when you supply a lambda expression to an expression tree.

Expression Trees vs. Lambda Expressions

A common misconception is that expression trees are identical to lambda expressions. This is not true. On the one hand, as I have already shown, you can create and modify expression trees by using API methods, without using lambda expression syntax at all. On the other hand, not every lambda expression can be implicitly converted into an expression tree. For example, multiline lambdas (also called statement lambdas) cannot be implicitly converted into expression trees.

// You can use multiline lambdas in delegates.

Action<int> printTwoLines = (arg) =>

{

Console.WriteLine("Print arg:");

Console.WriteLine(arg);

};

// But in expression trees this generates a compiler error.

Expression<Action<int>> printTwoLinesExpr = (arg) =>

{

Console.WriteLine("Print arg:");

Console.WriteLine(arg);

};

Expression Trees in Visual Studio 2010

All the code examples I have shown so far work (or don’t work) the same in both Visual Studio 2008 and Visual Studio 2010. Now let’s move to C# 4.0 and Visual Studio 2010.

In Visual Studio 2010, the expression trees API was extended and added to the dynamic language runtime (DLR), so that language implementers can emit expression trees rather than MSIL. To support this new goal, control flow and assignment features were added to expression trees: loops, conditional blocks, try-catch blocks, and so on.

There is a catch: You cannot use these new features “an easy way”, by using lambda expressions syntax. You must use the expression trees API. So the last code example in the previous section still generates a compiler error, even in Visual Studio 2010.

But now you have a way to create such an expression tree by using API methods that were not available in Visual Studio 2008. One of these methods is Expression.Block, which enables the execution of several expressions sequentially, and this is exactly the method that I need for this example.

// Creating a parameter for an expression tree.

ParameterExpression param = Expression.Parameter(typeof(int), "arg");

// Creating an expression for printing a constant string.

MethodCallExpression firstMethodCall = Expression.Call(

typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) }),

Expression.Constant("Print arg:")

);

// Creating an expression for printing a passed argument.

MethodCallExpression secondMethodCall = Expression.Call(

typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) }),

param

);

// Creating a block expression that combines two method calls.

BlockExpression block = Expression.Block(firstMethodCall, secondMethodCall);

// Compiling and invoking an expression tree.

Expression.Lambda<Action<int>>(

block,

new ParameterExpression[] { param }

).Compile()(10);

I’ll repeat this: Although the expression trees API was extended, the way expression trees work with lambda expression syntax did not change. This means that LINQ queries in Visual Studio 2010 have the same features (and the same limitations) that they had in Visual Studio 2008.

But because of the new features, you can find more areas outside of LINQ where you can use expression trees.

Generating Dynamic Methods

Now let’s move to the real problems where the new API can help. The most well-known one is creating dynamic methods. The common solution to this problem is to use System.Reflection.Emit and work directly with MSIL. Needless to say, the resulting code is hard to write and read.

Basically, the expression tree that prints two lines to the console that I have shown previously is already an example of a dynamic method. But let’s try a little bit more complex one to demonstrate more features of the new API. Thanks to John Messerly, a developer on the DLR team, for providing the following example.

Assume that you have a simple method that calculates the factorial of a number.

static int CSharpFact(int value)

{

  int result = 1;

while (value > 1)

{

result *= value--;

}

return result;

}

Now you want a dynamic method that does the same thing. We have several essential elements here: a parameter that is passed to a method, a local variable, and a loop. This is how you can represent these elements by using the expression trees API.

static Func<int, int> ETFact()

{

// Creating a parameter expression.

ParameterExpression value = Expression.Parameter(typeof(int), "value");

// Creating an expression to hold a local variable.

ParameterExpression result = Expression.Parameter(typeof(int), "result");

// Creating a label to jump to from a loop.

LabelTarget label = Expression.Label(typeof(int));

// Creating a method body.

BlockExpression block = Expression.Block(

// Adding a local variable.

new[] { result },

// Assigning a constant to a local variable: result = 1

Expression.Assign(result, Expression.Constant(1)),

// Adding a loop.

Expression.Loop(

// Adding a conditional block into the loop.

Expression.IfThenElse(

// Condition: value > 1

Expression.GreaterThan(value, Expression.Constant(1)),

// If true: result *= value --

Expression.MultiplyAssign(result,

Expression.PostDecrementAssign(value)),

// If false, exit from loop and go to a label.

Expression.Break(label, result)

),

// Label to jump to.

label

)

);

// Compile an expression tree and return a delegate.

return Expression.Lambda<Func<int, int>>(block, value).Compile();

}

Yes, this may look more complicated and less clear than the original C# code. But compare it to what you have to write to generate MSIL.

static Func<int, int> ILFact()

{

      var method = new DynamicMethod(

      "factorial", typeof(int),

      new[] { typeof(int) }

      );

      var il = method.GetILGenerator();

      var result = il.DeclareLocal(typeof(int));

      var startWhile = il.DefineLabel();

      var returnResult = il.DefineLabel();

      // result = 1

      il.Emit(OpCodes.Ldc_I4_1);

      il.Emit(OpCodes.Stloc, result);

      // if (value <= 1) branch end

      il.MarkLabel(startWhile);

      il.Emit(OpCodes.Ldarg_0);

      il.Emit(OpCodes.Ldc_I4_1);

      il.Emit(OpCodes.Ble_S, returnResult);

      // result *= (value--)

      il.Emit(OpCodes.Ldloc, result);

      il.Emit(OpCodes.Ldarg_0);

      il.Emit(OpCodes.Dup);

      il.Emit(OpCodes.Ldc_I4_1);

      il.Emit(OpCodes.Sub);

      il.Emit(OpCodes.Starg_S, 0);

      il.Emit(OpCodes.Mul);

      il.Emit(OpCodes.Stloc, result);

      // end while

      il.Emit(OpCodes.Br_S, startWhile);

      // return result

      il.MarkLabel(returnResult);

      il.Emit(OpCodes.Ldloc, result);

      il.Emit(OpCodes.Ret);

      return (Func<int, int>)method.CreateDelegate(typeof(Func<int, int>));

}

If You Want to Know More

In Visual Studio 2010, expression trees were developed as a part of the dynamic language runtime, which is also released as an open-source project. You can download the source code and find the specification and documentation for expression trees on the CodePlex Web site.

A more advanced example of using the new expression trees API is shown in Bart De Smet's blog post Expression Trees, Take Two – Introducing System.Linq.Expressions v4.0.

And of course, to try the examples, you need to download Visual Studio 2010 and .NET Framework 4 Beta 1 here.