tags:

views:

432

answers:

1

Hi there,

I'm building a C# expression tree to evaluate simple expressions. The expression strings are parsed into trees, and respect the basic operators (mathematical, logical and relational) as well as precedence through the use of parantheses.

In addition to the types bool, string and integer - I require some of the elements of the expression to be evaluated at runtime. These are represented by templated strings, for example:

([firstname] == "bob") && ([surname] == "builder")

The above expression would be evaluated for a (potentially large) number of objects that provide the context for the current expression invocation, for example, in a loop. The templated section would be used reflectively on the current context - e.g. the current user's firstname and surname would be resolved in the example and those values used in the expression resolution rather than the templated strings.

One solution would be to resolve the templated value at parse time, that way a constant expression type could be used and the type of the value would be known. However, re-building and re-compiling the expression tree each use would have bad for performance.

So, I need an expression type whose: - value type is not known at parse time, and - which is resolved by a method call at invoke time

E.g. Desired example of usage in pseudo code
ExpressionParser parser = new ExpressionParser(); // parses and builds expression trees
MyParsedExpression expression = parser.Parse("([firstname] == 'bob') && ([surname] == 'builder'"); // wrapper for the parsed expression
foreach (Object user in users)
{
    expression.Context = user;
    Boolean result = expression.EvaluateTruth(); 
    if (result == true)
    {
       // do something
    }
}

Thanks, fturtle

+2  A: 

Use a ParameterExpression to represent an incoming parameter. As for the type exception... do you know the type of the data when you build the expression tree? If not, that does make things a lot harder...

If it's any use to you, I answered a similar question recently, with some source code. It may not be immediately usable to you, but it should be a good start.

EDIT: I'm not sure that expression trees are going to be very much use to you here. In particular a PropertyExpression contains the relevant PropertyInfo, so it needs to know the type it's working with. If the type could change for every value, you'd have to rebuild the expression tree for every value...

Jon Skeet
Cheers for the response. I'm not sure a parameter expression is going to help me here, as the expressions can be nested and may contain any number of templated values. Additionally, the type isn't known when the expression tree is built. In summary, I guess I'm after some sort of delegate expression.
fturtle
I'm afraid it's not really very clear what you're trying to do, and what information is known at what time. Have you already got the parsing side of things? What information *do* you have, and what don't you have? Could you store some intermediate form which lets you build a strongly typed expression tree later?
Jon Skeet