WP7 #3: Compiling Expressions

Just a short post today about how to compile Expressions under Windows Phone 7.

Expression Trees are a powerful feature since .NET 3.0. They can be used to create executable code fragments dynamically at runtime and have a wide range of purposes, for example to implement the Specification Pattern and Guard Classes. After you’ve built up your expression tree (which is a tree representation of real code), you can execute your code fragment by calling expression.Compile().Invoke().

When it comes to Windows Phone 7, that’s a problem… because there is no Compile() method on the Expression class. Since the WP7 platform has limitations at some points (regarding dynamic coding, Reflection, etc.), it doesn’t have a Compile() method at the moment (let’s hope the MS guys are fixing this in the near future…).

One solution I came across with can be found here. Those guys take the Expression compiler from the Mono project and use it instead. With a call of ExpressionCompiler.Compile(expression) you’re able to compile an expression. It works, sadly it’s kind of limited: the Expression compiler makes use of Reflection – since Silverlight doesn’t support Reflection on private members, all members used in the Expression must be public. This limits the range of this solution, so let’s hope that Microsoft will adopt the WP7 platform at this point…

The sources and binary DLL of the Expression compiler can be found here for free (MIT license): [Download]

C#: Efficient retrieval of Expression values

Some days ago I’ve had an interesting technical discussion with a colleague of mine regarding the possibility of implementing Guard classes with Expressions in C#. Such a class enables easy argument checking in form of (technical) preconditions on method entry. Thereby the checking logic is encapsulated in the Guard class.

One method of such a Guard class could be AssertNotNull() which checks, if a given method argument equals null and if true throws an ArgumentNullException. By the use of Expressions the parameter to check can be given to AssertNotNull() in a very elegant way:

public void MyMethod(SomeType elem)
{
    Guard.AssertNotNull(() => elem);

    // actual method logic
}

Through evaluation of the Expression the AssertNotNull() method is able to extract both the name and value of the argument. Thus there’s no necessity to provide both as parameters to AssertNotNull(). Moreover you do not need to provide the argument name as string.

Value by compilation

It’s very easy to extract the argument value through compilation and invocation of the Expression. Hence this solution is often taken by developers who work with Expressions in this way. The following snippet shows this implementation:

public static class Guard
{
    public static void AssertNotNull<T>(Expression<Func<T>> selector)
    {
        T value = selector.Compile().Invoke();
        if (value == null)
        {
            string name = ((MemberExpression)selector.Body).Member.Name;
            throw new ArgumentNullException(name);
        }
    }
}

Value by evaluation

In the conversation with my colleague we caught the point that the extraction of the argument value from an Expression is even possible without performing the costly compilation. This is enabled by converting the Expression into a ConstantExpression, from which we can catch the value by executing GetValue() on a FieldInfo instance:

public static class Guard
{
    public static void AssertNotNull<T>(Expression<Func<T>> selector)
    {
        var memberSelector = (MemberExpression)selector.Body;
        var constantSelector = (ConstantExpression)memberSelector.Expression;
        object value = ((FieldInfo)memberSelector.Member)
            .GetValue(constantSelector.Value);

        if (value == null)
        {
            string name = ((MemberExpression)selector.Body).Member.Name;
            throw new ArgumentNullException(name);
        }
    }
}

This doesn’t look very spectacular on first sight. The code is more complicated and it’s necessary to provide a variable in the Expression. Properties and data hierarchies don’t work with this solution, but this shouldn’t be a problem when checking argument values against null. Of course with a more sophisticated solution (iterative/recursive evaluation of the Expression tree) you can enable such scenarios, but this is out of scope of this blog post…

Looking at the execution times

So what’s the point of the second solution? It’s simple: compilation is much more time-intensive! In a little runtime test I’ve compared both solutions. A call of AssertNotNull() with a valid argument (!= null) over 10.000 iterations resulted in the following execution times:

Please note the immensive time difference! The compiled solution takes more than 53 seconds, while the evaluation takes less than 0,35 seconds. This makes a time factor of more than 156, by which the evaluated solution is faster than the compiled approach.

Conclusion

When handling with Expressions you should take the execution time into account! Once a method is executed inside of a loop and you follow defensive programming and check method parameters at every place, an argument check can become an important time factor. When possible you should favor evaluation over compilation of Expressions.

kick it on DotNetKicks.com