Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implement Not in expression trees, .net 4

Is it possible to implement a ! (not) using expression trees. I'm interested in creating a C# eval class which will parse and evaluate logical expressions which contain true, false, ||, && and !. I know that && and || are currently supported by .NET 4 expression trees, but I was wondering if their is a way to implement summat like !(x && y) || z where z=false, y=true and z=false.

Currently I'm using a standard stack based tokenizer, parser, evaluator to evaluate these types of expression but would happly dump it, if a suitable expression tree could be created and executed on the fly.

like image 371
scope_creep Avatar asked Jan 29 '10 20:01

scope_creep


People also ask

Why do we need expression trees C#?

When you want to have a richer interaction, you need to use Expression Trees. Expression Trees represent code as a structure that you can examine, modify, or execute. These tools give you the power to manipulate code during run time. You can write code that examines running algorithms, or injects new capabilities.

What type allows the C# compiler to build an expression tree from code?

The C# compiler can generate expression trees only from expression lambdas (or single-line lambdas). It cannot parse statement lambdas (or multi-line lambdas). For more information about lambda expressions in C#, see Lambda Expressions.

What is more complex expression tree?

That's the basics of building an expression tree in memory. More complex trees generally mean more node types, and more nodes in the tree. Let's run through one more example and show two more node types that you will typically build when you create expression trees: the argument nodes, and method call nodes.


1 Answers

I usually find that it's worth coding a lambda expression which does what I want, and then seeing what the C# compiler does with it.

So this code:

Expression<Func<bool,bool>> func = x => !x;

Is compiled into:

ParameterExpression expression2;
Expression<Func<bool, bool>> expression = 
       Expression.Lambda<Func<bool, bool>>(Expression.Not(
            expression2 = Expression.Parameter(typeof(bool), "x")), 
                new ParameterExpression[] { expression2 });

(Apologies for the formatting - it's hard to know what to do with that.)

That's decompiled with Reflector, but with its "optimization" set at .NET 2.0 to avoid it using lambda syntax.

Once you've got past the junk, you'll see it's using Expression.Not. && uses Expression.AndAlso, and || uses Expression.OrElse.

like image 101
Jon Skeet Avatar answered Sep 30 '22 06:09

Jon Skeet