Реализация Не в деревьях выражений, .net 4 - PullRequest
4 голосов
/ 29 января 2010

Возможно ли реализовать! (не) используя деревья выражений. Я заинтересован в создании класса C # eval, который будет анализировать и оценивать логические выражения, которые содержат истину, ложь, ||, && и! Я знаю, что && и || в настоящее время поддерживаются деревьями выражений .NET 4, но мне было интересно, есть ли способ реализовать их как summat! (x && y) || z, где z = ложь, y = истина и z = ложь.

В настоящее время я использую стандартный основанный на стеке токенайзер, анализатор и оценщик для оценки этих типов выражений, но с радостью сбросил бы его, если бы подходящее дерево выражений могло быть создано и выполнено на лету.

Ответы [ 3 ]

11 голосов
/ 29 января 2010

Я обычно нахожу, что стоит кодировать лямбда-выражение, которое делает то, что я хочу, а затем посмотреть, что с ним делает компилятор C #.

Итак, этот код:

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

Составлено в:

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

(Извиняюсь за форматирование - сложно понять, что с этим делать.)

Он декомпилирован с помощью Reflector, но его «оптимизация» установлена ​​на .NET 2.0, чтобы избежать использования лямбда-синтаксиса.

Как только вы пройдете через мусор, вы увидите, что он использует Expression.Not. && использует Expression.AndAlso и || использует Expression.OrElse.

2 голосов
/ 29 января 2010

Это уже существует в System.Linq.Expressions. См. UnaryExpression . Если в выражениях вам что-то не нравится, я бы предложил их использовать. Существуют также способы создания абстрактных синтаксических деревьев из исходного кода, в частности в Microsoft.Scripting.Ast (находится в DLR: Microsoft.Scripting).

0 голосов
/ 29 января 2010
...