This month, I resurrect my series on breaking down complex techniques to a few simple steps that provides a reasonable basis for you to learn the essentials and then take that knowledge to the next level. This is a first in a series that focuses on .NET's dynamic language capabilities.

Two of .NET's most powerful features are the Expression Trees and Lambda Expressions. Even so, they continue to be misunderstood despite the fact that they've been part of .NET since 2009. In 2010, the Dynamic Type was introduced and that gave us the ability to create dynamic lambda expressions.

In this article, I'll break through the numerous convoluted examples that you may have already encountered and show you the basics of what you need to get productive right away with dynamic lambda expressions. Lambda's and expression trees can get complex. Instead of focusing on the minutia, I'm going to cut through to the good stuff.

Data Classes and Data Set

To get started, you need a sample data set. Listing 1 illustrates the data classes that will be used for the examples in this article. Listing 2 illustrates the sample data set.

Listing 1: Data Classes

public class Address
{
    public string Number { get; set; }
    public string Street { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zipcode { get; set; }
}
public class Person
{
    public Person()
    {
        this.Address = new Address();
    }

    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Address Address { get; set; }
    public int Age { get; set; }
}

Listing 2: Data Set

private List<Person> _people = new List<Person>();
var person = new Person();
person.FirstName = "John";
person.LastName = "Doe";
person.Age = 29;
person.Address.Number = "1234";
person.Address.Street = "Main Street";
person.Address.City = "Philadelphia";
person.Address.State = "PA";
person.Address.Zipcode = "19101";

_people.Add(person);

person = new Person();
person.FirstName = "Bob";
person.LastName = "Smith";
person.Age = 65;
person.Address.Number = "123";
person.Address.Street = "Lancaster Avenue";
person.Address.City = "Paoli";
person.Address.State = "PA";
person.Address.Zipcode = "19301";

_people.Add(person);

A Simple Lambda Expression Query

Just about every application requires some form of data access and query capability. Using the data classes and data set illustrated in Listing 1 and Listing 2 respectively, you can employ the following query to find all people with the first name of John:

var result = _people.Where(person => person.FirstName
    == "John").ToList();

Lambda expressions, like is the one illustrated above, are very powerful. There is also some inflexibility, although you can easily vary the value you use to compare to the FirstName property. What if you want to vary the property? That is, as it turns out, a bit more complicated.

In the next section, I'll convert the query listed above to be dynamic so that it can be built and compiled at run time.

Creating Your First Dynamic Lambda Expression

The key to understanding how to create dynamic lambda expressions rests with understanding the Expressions class, which is part of the System.Linq.Expressions namespace. The first step is to create a parameter expression that allows you to validate and compile against a known type. In this case, the type is in the Person and Address classes:

var parameterExpression =
    Expression.Parameter(Type.GetType(
        "ExpressionTreeTests.Person"), "person");

Once you have you parameter expression, you can begin to build the additional components. The following code creates an expression constant:

var constant = Expression.Constant("John");

The expression constant has to be compared to some property. The code in the next snippet creates a property expression.

var property = Expression.Property(parameterExpression,
    "FirstName");

Note that the parameter expression created earlier is used to validate the property. If the property name passed as a string isn't found for the specified type, an error is thrown.

Next, you need to bring the expression constant and property together. In this case, you wish to test whether or not a property is equal to a string constant. The following code brings those two expressions together:

var expression = Expression.Equal(property, constant);

The expression variable's string representation is:

{(person.FirstName == "John")}

Once an expression has been created, you can create a lambda expression. The next code snippet accomplishes that task:

var lambda = Expression.Lambda<Func<Person,
    bool>>(expression, parameterExpression);

In this case, the lambda represents a delegate function that accepts a Person argument and returns a Boolean value to indicate whether the specified Person object meets the query criteria. In this case, the query criterion is whether the FirstName == "John". The following illustrates the string representation of the dynamic lambda expression:

{person => (person.FirstName == "John")}

This is identical to the lambda expression in the simple lambda expression query listed above. The only difference is that instead of embedding the definition in the code, you've built it dynamically. The last step before using the dynamic lambda expression is to compile it:

var compiledLambda = lambda.Compile();

Now that the lambda is compiled, you can use it in a query:

var result = _people.Where(compiledLambda).ToList();

That's it. That's all there is to building a simple dynamic lambda expression. What if you have compound criteria? Let's tackle that next.

Creating a Dynamic Lambda with Compound Criteria

The following is an example lambda expression with compound criteria:

var result = _people.Where(person => person.FirstName ==
    "John" || person.Address.City == "Paoli" ).ToList();

To duplicate the code dynamically, you can start with the same elements as in the first example:

var parameterExpression =
    Expression.Parameter(Type.GetType(
        "ExpressionTreeTests.Person"), "person");
var constant = Expression.Constant("John");
var property = Expression.Property(parameterExpression,
    "FirstName");
var expression = Expression.Equal(property, constant);

Next, you need to build up the second expression. This one is a bit more complicated because the City property is a member of an object that is, in turn, a member of the Person class: Person.Address.City. You might think that you could simply write this code:

var property = Expression.Property(parameterExpression,
    "Address.City"); //This will not work

Instead, you have to traverse the hierarchy in order to validate nested properties:

Expression property2 = parameterExpression;
foreach (var member in "Address.City".Split('.'))
{
    property2 = Expression.PropertyOrField(property2, member);
}

With the property expression resolved, you can now join it to the constant:

constant = Expression.Constant("Paoli");
var expression2 = Expression.Equal(property2, constant);

The next step involves joining the two expressions:

expression = Expression.Or(expression, expression2);

The rest of the code is like the previous example:

var lambda = Expression.Lambda<Func<Person,
    bool>>(expression, parameterExpression);
var compiledLambda = lambda.Compile();
var result = _people.Where(compiledLambda).ToList();

The following illustrates the generated lambda:

{person => ((person.FirstName == "John") Or
    (person.Address.City == "Paoli"))}

In the next installment, I'll illustrate how to create dynamic lambda expressions in the context of dictionaries that consist of a string,object pair. On one hand, string,object pairs are very flexible in that anything can be stored as an object. On the other hand, querying a dictionary of string,object requires you to cast the object to a specific data type. Add dynamic lambdas to the mix, and the challenge is greater. I'll cover those situations next time.