Оценить выражение как строку, вернуть объект? - PullRequest
3 голосов
/ 11 апреля 2011

В основном у меня есть некоторый код, где, когда это происходит, мне нужно установить некоторый объект, равный некоторому выражению.Весь этот джаз "что делать" хранится в виде строки.Поэтому я анализирую его и использую отражение, чтобы найти объект, для которого я это делаю.Теперь мне нужно выяснить, как сохранить значение этого объекта.Проблема в том, что значение может быть «1», «1 * (5/2)» ​​или «некоторое строковое значение».Было бы здорово, если бы у меня могли быть выражения типа «this.SomeProperty» или «(x> 3? 4: 5)».

Кроме того, объект, который он хранит, может быть строкой, int, удвоить или плавать как минимум.

Ответы [ 2 ]

1 голос
/ 12 апреля 2011

Образцы VS2008 включали в себя отличную ExpressionParser, которую можно использовать в качестве синтаксического анализатора обобщенных выражений ( Образцы VS2008 ). С помощью нескольких небольших обновлений и пользовательского класса фабрики мы можем превратить его в нечто более выразительное:

string expression = "(1 + 2)";
var func = FunctionFactory.Create<int>(expression);

Или:

expression = "(a * b)";
var func2 = FunctionFactory.Create<int, int, int>(expression, new[] { "a", "b" });

Возвращаемыми типами этих Create методов являются Func<> экземпляры, что означает, что мы получаем хорошие строго типовые делегаты:

int result = func2(45, 100); // result = 450;

Я отправил код в гист

Обновление : я недавно тоже писал об этом .

Обновление 2 , другой пример:

var person = new Person { Age = 5 };
string expression = "(Age == 5)";
var func3 = FunctionFactory.Create<Person, bool>(expression);

bool isFive = func3(person); // Should be true.
0 голосов
/ 10 августа 2011

Вы видели http://ncalc.codeplex.com?

Это расширяемое, быстрое (например, имеет собственный кэш) позволяет вам предоставлять пользовательские функции и переменные во время выполнения путем обработки событий EvaluateFunction / EvaluateParameter. Примеры выражений, которые он может анализировать:

Expression e = new Expression("Round(Pow(Pi, 2) + Pow([Pi2], 2) + X, 2)"); 

  e.Parameters["Pi2"] = new Expression("Pi * Pi"); 
  e.Parameters["X"] = 10; 

  e.EvaluateParameter += delegate(string name, ParameterArgs args) 
    { 
      if (name == "Pi") 
      args.Result = 3.14; 
    }; 

  Debug.Assert(117.07 == e.Evaluate()); 

Он также обрабатывает Unicode и многие типы данных изначально. Он поставляется с файлом рога, если вы хотите изменить грамматику. Существует также форк, который поддерживает MEF для загрузки новых функций.

...