views:

37

answers:

3

hello... I'm just in the early process of learning about expression trees.

As far as I understand, the good thing about them is that they can be parsed when they are used as parameters, so for instance:

Foo.Bar(x => x.Process == "On" && x.Name == "Goofy")

But how can I parse the expression when there is AND inside?

Maybe I've misunderstood it all, but then I can't see the reason for using expressions? I've now looked at nearly hundreds of websites that all try to explain what an expression tree are and they all succeeded, expect they never explained what the use was - except the trivial explanation "An expression tree is not compiled...."

A: 

I have used Expressions to build a trivial Domain Specific Language. This is used in an actual application where I work, so it's not a toy project.

I basically created a fluent interface that allows me to build Predicate<T> delegates, something like:

Predicate<MyClass> condition = (new ConditionBuilder()).GreaterThanConst(9)
                                                       .And()
                                                       .LessThanConst(4)
                                                       .ToPredicate();

Each method adds the relevant expression to the current tree. Than ToPredicate compiles the expression to the delegate.

The GreaterThanConst method looks something like:

public ConditionBuilder GreaterThan(object constant)
{
    condition = Expression.GreaterThan(Expression.Parameter(constant.GetType()), Expression.Constant(constant));
    return this;
}

Where condition is the member that holds the tree that's being built (grown?).

To parse your expression, you'd need to write something like:

Expression<Func<YourClass, bool>> expr = x => x.Process == "On" && x.Name == "Goofy";

Then you can look though the expression tree that is generated and see what's there.

Matt Ellen
Thank you for this... well yes, I did imagine something like extensionpublic static bool Bar(this Foo foo, Expression<Func<YourClass, bool>> expr){...}And then look into the expression tree, calculate either false or true and then return.Am I on the right track here?
Janus007
I'm not sure why you'd need an expression tree for that. It would make more sense to just pass in the `Func` its self, if all you intend to do is return the result.
Matt Ellen
I was inspired by the following: NServiceBus.Configure.With().Log4Net(a => a.YourProperty = "value"); Setting a property like this :)
Janus007
A: 

Expressions represent code in the form of a tree. Each node of the tree represent a part of the code. For instance, the tree for the body of the lambda expression in your question is something like that:

BinaryExpression (AndAlso)
  .Left = BinaryExpression (Equal)
    .Left = MemberExpression (x.Process)
      .Expression = ParameterExpression (x)
      .Member = MemberInfo (Process)
    .Right = ConstantExpression ("On")
  .Right = BinaryExpression (Equal)
    .Left = MemberExpression (x.Name)
      .Expression = ParameterExpression (x)
      .Member = MemberInfo (Name)
    .Right = ConstantExpression ("Goofy")

Typically, the code represented by the expression is not executed, and not even compiled : it is analyzed to extract some information from it, to transform it into another expression, or even to generate something completely different (like a SQL query in Linq to SQL or Entity Framework). That wouldn't be possible with compiled code, because there would be no way to analyze it (at least not easily).

Thomas Levesque
Thank you for clarifying this, it was exactly what I had hoped :) It did answer my last question.
Janus007
A: 

I was inspired by the following:

NServiceBus.Configure.With().Log4Net(a => a.YourProperty = "value"); 

Setting a property like this :)
Sorry for posting this again, but I find it peculiar how the answers and comments are organized, I'm afraid my question disappears.

Janus007