Practical use of expression trees

C#Expression Trees

C# Problem Overview


Expression trees are a nice feature, but what are its practical uses? Can they be used for some sort of code generation or metaprogramming or some such?

C# Solutions


Solution 1 - C#

As Jon notes, I use them to provide generic operators with .NET 3.5. I also use them (again in MiscUtil) to provide fast access to non-default constructors (you can't use Delegate.CreateDelegate with constructors, but Expression works fine).

Other uses of manually created expression trees:

But really, Expression is a very versatile way of writing any dynamic code. Much simpler than Reflection.Emit, and for my money, simpler to understand than CodeDOM. And in .NET 4.0, you have even more options available. I show the fundamentals of writing code via Expression on my blog.

Solution 2 - C#

Marc Gravell has used them to great effect in MiscUtil to implement generic operators.

Solution 3 - C#

I just created a generic filter function using an Expression Tree that I want to share with you guys...

Start

var allFiltered= Filter(AllCustomer, "Name", "Moumit");

public static List<T> Filter<T>(this List<T> Filterable, string PropertyName, object ParameterValue)
{
    ConstantExpression c = Expression.Constant(ParameterValue);
    ParameterExpression p = Expression.Parameter(typeof(T), "xx");
    MemberExpression m = Expression.PropertyOrField(p, PropertyName);
    var Lambda = Expression.Lambda<Func<T, Boolean>>(Expression.Equal(c, m), new[] { p });
    Func<T, Boolean> func = Lambda.Compile();
    return Filterable.Where(func).ToList();
}

One More

string singlePropertyName=GetPropertyName((Property.Customer p) => p.Name);

public static string GetPropertyName<T, U>(Expression<Func<T, U>> expression)
{
        MemberExpression body = expression.Body as MemberExpression;
        // if expression is not a member expression
        if (body == null)
        {
            UnaryExpression ubody = (UnaryExpression)expression.Body;
            body = ubody.Operand as MemberExpression;
        }
        return string.Join(".", body.ToString().Split('.').Skip(1));
}

Make it more expandable

string multiCommaSeparatedPropertyNames=GetMultiplePropertyName<Property.Customer>(c => c.CustomerId, c => c.AuthorizationStatus)

public static string GetMultiplePropertyName<T>(params Expression<Func<T, object>>[] expressions)
{
        string[] propertyNames = new string[expressions.Count()];
        for (int i = 0; i < propertyNames.Length; i++)
        {
            propertyNames[i] = GetPropertyName(expressions[i]);
        }

        return propertyNames.Join();
}

I know it also can be done using reflection, but this one is tremendously fast or, I can say, equivalent to a lambda after first compilation. The very first iteration takes just an average of 10 milliseconds. So this is Expression Tree magic. Simple and fantastic (I think)!

Solution 4 - C#

I use them to create dynamic queries, whether it be for sorting or filtering the data. As an example:

IQueryable<Data.Task> query = ctx.DataContext.Tasks;
   
if (criteria.ProjectId != Guid.Empty)
      query = query.Where(row => row.ProjectId == criteria.ProjectId);
        
if (criteria.Status != TaskStatus.NotSet)
      query = query.Where(row => row.Status == (int)criteria.Status);

if (criteria.DueDate.DateFrom != DateTime.MinValue)
      query = query.Where(row => row.DueDate >= criteria.DueDate.DateFrom);

if (criteria.DueDate.DateTo != DateTime.MaxValue)
     query = query.Where(row => row.DueDate <= criteria.DueDate.DateTo);

if (criteria.OpenDate.DateFrom != DateTime.MinValue)
     query = query.Where(row => row.OpenDate >= criteria.OpenDate.DateFrom);

var data = query.Select(row => TaskInfo.FetchTaskInfo(row));

Solution 5 - C#

Implementation of LINQ providers is mostly done by processing expression trees. I'm also using them to remove literal strings from my code:

Solution 6 - C#

You can use them to build your own linq provider for a website like Google or Flickr or Amazon, your own website or another data provider.

Solution 7 - C#

Originally by Jomo Fisher, Gustavo Guerra published a revised version of the static string dictionary.

Where through Expression trees, a dynamic expression that provides a really (read: ridiculously) Dictionary.

The implementation creates a dynamic decision tree that select the corrent value according to the length of the input string, then by the first letter, then the second letter and so on.

This ultimately runs much faster than the equivalent Dictionary.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDmitri NesterukView Question on Stackoverflow
Solution 1 - C#Marc GravellView Answer on Stackoverflow
Solution 2 - C#Jon SkeetView Answer on Stackoverflow
Solution 3 - C#MoumitView Answer on Stackoverflow
Solution 4 - C#mattrumaView Answer on Stackoverflow
Solution 5 - C#Mauricio SchefferView Answer on Stackoverflow
Solution 6 - C#tuinstoelView Answer on Stackoverflow
Solution 7 - C#damageboyView Answer on Stackoverflow