Implement Not in expression trees, .net 4

2019-05-06 10:09发布

问题:

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.

回答1:

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.



回答2:

This already exists in System.Linq.Expressions. See UnaryExpression. Unless there is something about the expressions that you don't like, I would suggest using them. There are also ways to create abstract syntax trees from source code, specifically in Microsoft.Scripting.Ast (found in the DLR: Microsoft.Scripting).



回答3:

This might be useful: http://community.bartdesmet.net/blogs/bart/archive/2009/08/10/expression-trees-take-two-introducing-system-linq-expressions-v4-0.aspx