views:

590

answers:

9

This one was inspired by my language-guru co-worker who can't seem to find a good use for them, and after a few lame attempts of my own, I'd have to agree.

Now I know these concepts tend to flow a lot more easily once you get some good practical reasons down.

At the moment it seems as though its only purpose is to allow you to write a Linq provider?

Is that it?? Is there any other benefits to this?

+2  A: 

.NET 4.0 Expression trees are also the basis for DLR AST's

James Deville
+5  A: 

You can use Expression Trees to transform a domain language into executable code.

ChaosPandion
+1  A: 

I've had a good experience with them transforming my domain specific language ASTs into expression trees. It is also fairly easy with an ANTLR tree adaptor to create an Expression tree directly from the grammar.

sixlettervariables
+3  A: 

A Solution looking for a problem eh?

Expression trees allow you to present code as a transformable data-structure, hence they are perfect for transforming between languages Linq To SQL being the most powerful currently.

An other use apart from DSLs (which is transformation) is parallelization (which is spliting) and example in that space is PLINQ.

Jan Bannister
yes a solution looking for a problem like twitter :)
Surya
+1  A: 

see this post: http://codebetter.com/blogs/gregyoung/archive/2009/10/03/delegate-mapper.aspx It is a great use case.

Benny
+4  A: 

Expression tree are so powerful because they let you treat code like data. Users are accustomed to building up data, saving it and coming back to it later.

Expression trees let you do the same thing with code. For example you can take your user's input (check-boxes, number ranges, etc.) and translate it into an Expression tree. That expression tree can then be executed, or stored off for later use. Very cool.

Think of the practical uses around reporting like building up and saving data filters and data mappings. Another practical use would be to support custom work flows in your application based on user defined rules.

Here's a bit of MSDN code on serializing expression trees (http://code.msdn.microsoft.com/exprserialization) that should get the ideas flowing.

Bryan Hunter
Cool! This is an answer that fits my particular mindset. Nice examples!I see now how this is used in other parts of the framework. So then is this used a lot in WPF?
KevinDeus
Thanks. Glad that helped. I’ve thought (probably too much) about WPF and how crazy useful functional programming concepts like lambdas and expression trees would have been at the core. Problem is WPF was released with .NET 3.0 and LINQ was released in .NET 3.5. Going forward I would hope the WPF/Silverlight teams will retool. XAML would be OK except for all the darn strings :). Fire up Relector and see what they had to do for things like System.Windows.DataTrigger. Their lamentation may have been a catalyst for LINQ.
Bryan Hunter
+1  A: 

You can use expression tree as a code builder with a higher abstraction level then asembly emit and faster then CodeCompiler. Here is some proof of the concept that i used to convince our team to use them as a replacement for CodeCompiler.

[TestClass]
public class WhenINeedToAccessPropertiesByNameHavingATypeReference
{
 public class SomeCategoryData
 {
  public DateTime CreatedDate { get; set; }
 }
 [TestMethod]
 public void ICanDoThatWithAnExpressionAndItPerformsWell()
 {
  // INIT

  var someCategoryData =
   Enumerable.Range(1970, 100).Select(year=>
                new SomeCategoryData {CreatedDate = new DateTime(year,1,1)}).Cast<object>();
  var t = typeof(SomeCategoryData); // or it can be: t = someCategoryData.First().GetType();
  var compiled = Stopwatch.StartNew();

  // ACT

  var filter = AccessPropertyByNameInCompiledMannerSomehow(t, "CreatedDate");

  // ASSERT

  Trace.WriteLine(string.Format("compiled in: {0}", compiled.Elapsed));
  Assert.IsTrue(compiled.ElapsedMilliseconds < 3, "compiles fast enough");

  var executed = Stopwatch.StartNew();

  // ACT
  List<object> result = null;
  for (var i = 0; i < 10000; i++)
  {
   result = someCategoryData.Where(d => filter(d, new DateTime(2000, 1, 1), new DateTime(2009, 1, 1)))
    .ToList();
  }
  executed.Stop();
  Trace.WriteLine(string.Format("executed in: {0}", executed.Elapsed));

  // ASSERT
  Assert.AreEqual(10, result.Count, "insure compiled code actually works");
  Assert.IsTrue(executed.ElapsedMilliseconds < 300, "runs fast enough");
 }

 private static Func<object, DateTime, DateTime, bool>
  AccessPropertyByNameInCompiledMannerSomehow(Type t, string fieldToFilterBy)
 {
  var objectParameter = Expression.Parameter(typeof(object), "p");
  var instance = Expression.Convert(objectParameter, t);
  var lower = Expression.Parameter(typeof(DateTime), "l");
  var upper = Expression.Parameter(typeof(DateTime), "u");

  var composite = Expression.Lambda<Func<object, DateTime, DateTime, bool>>(
   Expression.And(
    Expression.LessThanOrEqual(
     lower,
     Expression.PropertyOrField(instance, fieldToFilterBy)
     ),
    Expression.GreaterThanOrEqual(
     upper,
     Expression.PropertyOrField(instance, fieldToFilterBy)
     )
    ), objectParameter, lower, upper
   );

  return composite.Compile();
 }
}
George Polevoy
+2  A: 

The quick answer is "no, it's not just for LINQ providers now". First, expression trees were extended by the dynamic language runtime to support dynamic languages. Basically, if you want to port your own dynamic language to .NET (like IronPython and IronRuby did), you will have to use expression trees. OK, not so many people have their own languages. What are other use cases? One of them is to generate dynamic code at run time. I have an example here: Generating Dynamic Methods with Expression Trees in Visual Studio 2010. It explains how you can use ETs instead of generating MSIL in order to create dynamic methods. In fact, there are some use cases for Expression Trees outside of LINQ even in .NET 3.5, but those posts are yet to be written.

Alexandra Rusina
+1  A: 

I have few examples here

( sorry about the broken code formatting )

Surya