71

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?

Dmitri Nesteruk
  • 23,067
  • 22
  • 97
  • 166
  • possible duplicate of [What are some instances in which expression trees are useful?](http://stackoverflow.com/questions/27726/what-are-some-instances-in-which-expression-trees-are-useful) – nawfal Oct 12 '13 at 14:49

7 Answers7

47

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.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
22

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

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
16

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)!

Dmitri Nesteruk
  • 23,067
  • 22
  • 97
  • 166
Moumit
  • 8,314
  • 9
  • 55
  • 59
12

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));
mattruma
  • 16,589
  • 32
  • 107
  • 171
8

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

Mauricio Scheffer
  • 98,863
  • 23
  • 192
  • 275
4

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.

tuinstoel
  • 7,248
  • 27
  • 27
2

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.

Community
  • 1
  • 1
damageboy
  • 2,097
  • 19
  • 34