Wednesday, October 21, 2009

Expression Trees .NET 3.5 Vs .NET 4.0 Part 1

Expression Trees is not a new technology.  In fact, they were first introduced with the release on .NET 3.0 which means that have been around for approximately 3 years.  Basically, Expression Trees represent language-level code in the form of data.  This data is stored on a tree shaped structure where each node represents an expression.  You can think of Expression Trees as a form of binary trees where each node contains zero, one or two children.  Based on this Binary Tree implementation the application can quickly search and find the value that is looking for.    If this is a totally new topic for you I suggest you read the Introduction to Expression Trees by Charlie Calvert in order to obtain a very clear idea about Expression Trees. 

I have been using Expression Trees for some time now, mainly in order to create a LINQ provider that connects to an HRMS application.  The development environment that I use is VS2008 and everything looks great so far.  Then a few days ago VS2010 Beta 2 was released and I started reviewing the enhancements/changes there, regarding Expression Trees. Well dear friend, I was stunned!!!  Microsoft people did delivered this time.  A significant amount of additional functionality that basically allows you to take full advantage of the upcoming DLR.  So this is the first of a series of small posts with examples regarding the enhancements/changes between Expression Trees in .NET 3.5 and .NET 4.0.

The first example is a console application created with VS2010 Beta2 that takes two numbers as input, compares them and returns a string with the comparison result.  First let’s take a look at the .NET 3.5 way of doing the comparison using expressions:

private static string WhatIsGreater(int value1, int value2)
{
    Func<int, int, string> compare = (inValue1, inValue2) =>
    {
        if (inValue1 == inValue2)
            return "Equal";
        if (inValue1 > inValue2)
            return "Value1 is Greater than Value2";
        if (inValue1 < inValue2)
            return "Value2 is Greater than Value1";

        return null;
    };

    return compare(value1, value2);

}

Nothing new here.  Just a method that returns a lambda expression.  Well see now the VS2010 approach for implementing the same thing using all the new extension methods of the Expressions.

private static string WhatIsGreaterNew(int value1, int value2)
{
    var result = Expression.Variable(typeof(string), "result");
    var inputValue1 = Expression.Parameter(typeof(int), "inputValue1");
    var inputValue2 = Expression.Parameter(typeof(int), "inputValue2");

    var compare = Expression.Lambda<Func<int, int, string>>
        (
            Expression.Block
            (
                new[] { result },
                Expression.Block
                (
                    Expression.Assign
                    (
                        result,
                        Expression.Constant(String.Empty)
                    )
                ),
                Expression.Block
                (
                    Expression.IfThen
                    (
                        Expression.Equal(inputValue1, inputValue2),
                        Expression.Assign
                        (
                                result,
                                Expression.Constant("Equal")
                        )
                    ),
                    Expression.IfThen
                    (
                        Expression.GreaterThan(inputValue1, inputValue2),
                        Expression.Assign
                        (
                                result,
                                Expression.Constant("Value1 is Greater than Value2")
                        )
                    ),
                    Expression.IfThen
                    (
                        Expression.LessThan(inputValue1, inputValue2),
                        Expression.Assign
                        (
                                result,
                                Expression.Constant("Value2 is Greater than Value1")
                        )
                    )
                ),
                result
            ),
            inputValue1,
            inputValue2

        ).Compile();

    return compare(value1, value2);
}

Hm!  A little bit more different, right?  So let’s describe the main differences here:

1.  We declare two Expression.Parameters that we use in order to compare the values inside the expression.  As you can see these parameters come right after the main Expression body.

2.  We declare an Expression.Variable that we will use in order to return the result of the comparison.

3.  The flow inside the Expression body is a follows:

3.1 declare the variable and initialize it.  Notice the Expression.Assign for initialization purpose

3.2 Compare the expression using simple if statements, an example using Expression.Switch will be posted soon, and assign the return value with the process result.

What is very important to notice is that while in .NET 3.5 it was all about expressions, in .NET 4.0 it is about expressions and statements.  This is now really powerful!  We can mutate variables, express sequence of operations and finally do dynamic dispatch using DLR to its maximum.

I am not a smoker and this is the SmokingCode!

No comments:

Post a Comment