Оценка выражения во время выполнения - PullRequest
4 голосов
/ 04 января 2011

У меня есть проект консольного приложения C #.

У меня есть логическое выражение, которое хранится в базе данных как nvarchar.

Например, сохраненное выражение: ((34> 0)|| (US == ES)) && (4312 = 5691)

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

Как я могу сделать это во время выполнения?

Ответы [ 2 ]

7 голосов
/ 04 января 2011

Вот довольно необычное решение, включающее JScript:

  • Создайте класс JScript со следующим кодом:

    public class JsMath {
        public static function Eval(expression:String) : Object {
            return eval(expression);
        }
    }
    
  • Скомпилируйте его в DLL:

    jsc /target:library /out:JsMath.dll JsMath.js
    
  • В вашем проекте на C # ссылки JsMath.dll и Microsoft.JScript.dll

  • Теперь вы можете использовать метод Eval следующим образом:

    string expression = "((34 > 0) || ('US' == 'ES')) && (4312 == 5691)";
    bool result = (bool)JsMath.Eval(expression);
    

Преимущества:

  • для анализа выражения не требуется никакой работы, движок JScript сделает это за вас
  • нет необходимости компилировать произвольный код (который может стать большой дырой в безопасности, если код введен пользователем)
  • должно работать с любым простым математическим или логическим выражением, если оно соответствует синтаксису JScript

Недостатки:

  • нет способа передать переменные (насколько я знаю)
  • требуется ссылка на сборку JScript (в большинстве случаев это не большая проблема, но я не уверен, что эта сборка доступна в профиле клиента или в Silverlight)
3 голосов
/ 04 января 2011

Вы можете проанализировать выражение в классе .NET Expression, скомпилировать и запустить его, чтобы получить результат.

Класс уже поддерживает все имеющиеся у вас логические операциив вашем примере, хотя это выглядит неоднозначно (вы используете == и = очень похожим образом).

Вы должны будете написать свой собственный анализатор / преобразователь.

...