Tip 54 – How to improve performance using Statement Expressions


While writing the update post in my Data Service Provider series I ended up writing this block of reflection code to copy properties values from one object to another:

foreach (var prop in resourceType 
         .Where(p => (p.Kind & ResourcePropertyKind.Key) 
                         != ResourcePropertyKind.Key))
    var clrProp = clrType
           .Single(p => p.Name == prop.Name); 
    var defaultPropValue = clrProp
           .Invoke(resetTemplate, new object[] { }); 
      .Invoke(resource, new object[] { defaultPropValue }); 


This code has at least two major problems.

  1. It is finding properties and methods via reflection in a loop
  2. It is invoking those methods using reflection in a loop.

We could address (1) by storing all the property get / set methods in some cacheable data-structure.

But fixing (2) is a little more tricky, to make this code truly generic you need to use something like lightweight code-gen, or worse.


Thankfully .NET 4.0 adds statement expressions. Which means you can create expressions that describe multi-line statements now, and yes those statements can do things like assignments.

Picture Borat saying ‘Nice…’

A quick search of the interweb revealed this excellent post on statement expressions by Bart, and that was enough to get me – and I hope you – to get excited.

Step 1 – Getting familiar with the API

Armed with my new found enthusiasm I decided to dip my toes in the water with something simple, namely trying to convert this into an expression:

Func<int> func = () => {
    int n; 
    return n;

It would be awesome if you could just do this:

Expression<Func<int>> expr = () => {
    int n; 
    n = 2;
    return n;

But unfortunately C# doesn’t support this today, instead you have to manually construct the expression, like this:

var n = Expression.Variable(typeof(int));
var expr = Expression.Lambda<Func<int>>
        // int n;
        new[] { n },
        // n = 2;
        // return n;


Pretty easy huh.

Step 2 – Proving we can assign to a property

Now we’ve got a feel for the API, it’s time to start applying it to our problem.

What we need is a function that will modify an Object (in this case a product) by resetting one or more of its properties, like this:

Action<Product> baseReset = (Product p) => { p.Name = null; };

This code creates an equivalent action using the new expression APIs:

var parameter = Expression.Parameter(typeof(Product));   
var resetExpr = Expression.Lambda<Action<Product>>(
                Expression.Constant(null, typeof(string))
var reset = resetExpr.Compile();
var product = new Product { ID = 1, Name = “Foo” };

And sure enough after reset(product) is called the product Name is null.

Step 3 – Assigning to all non key properties

Now all we need to do is create a function that when given a particular CLR type will create an expression to reset all the non-key properties.

Actually collecting the list of properties and their intended values, isn’t interesting for this discussion, so lets imagine we’ve already got that information in a dictionary, like this:

var properties = new Dictionary<PropertyInfo, object>();
var productProperties = typeof(Product).GetProperties();

var nameProp = productProperties.Single(p => p.Name == “Name”);
var costProp = productProperties.Single(p => p.Name == “Cost”);
properties.Add(nameProp, null);
properties.Add(costProp, 0.0M);

Given this data-structure our job is to create an expression that has the same affect as this action:

Action<Product> baseReset = (Product p) => {
       p.Name = null; 
       p.Cost = 0.0M;

First we need to create all the assignment expressions:

var parameter = Expression.Parameter(typeof(Product));
List<Expression> assignments = new List<Expression>();
foreach (var property in properties.Keys)
        Expression.Property(parameter, property.Name),

Next we feed the assignment expressions into a block inside a lambda, compile the whole thing and test out our nifty new function:

var resetExpr = Expression.Lambda<Action<Product>>(
var reset = resetExpr.Compile();
var product = new Product { ID = 1, Name = “Foo”, Cost = 34.5M };
Debug.Assert(product.Name == null);
Debug.Assert(product.Cost == 0.0M);

As expected this works like a charm.

To solve the problem I had in my Update Post, we’d need a dictionary keyed on type, that we can used to store the reset action for a particular type. Then if a type’s reset action it isn’t found we just create it…

And our performance problem should be a thing of the past 🙂

Comments (2)

  1. John says:

    Curious if you have performance numbers using Expressions over the nested reflection

  2. Alex D James says:


    I’ve got no perf numbers specific to this technique, but it should be a significant difference, its essentially the difference between normal code (once the expression is compiled) and reflection.