将表达式计算为字符串,返回对象?

时间:2011-04-11 19:11:18

标签: c# reflection runtime compilation

基本上我有一些代码,当它发生时,我需要设置一些等于某个表达式的对象。所有这些“做什么”爵士乐都存储为一个字符串。所以我解析它,并使用反射来找到我正在做的对象。现在我需要找出如何将值存储到此对象。问题是值可能是“1”,“1 *(5/2)”或“某个字符串值”。如果我能有像“this.SomeProperty”或“(x> 3?4:5)”这样的表达式,那真的很酷。

此外,它存储的对象至少可以是字符串,int,double或float。

2 个答案:

答案 0 :(得分:1)

VS2008样本包含一个漂亮的ExpressionParser,它可以用作通用表达式解析器(VS2008 Samples)。通过一些小更新和一个自定义工厂类,我们可以把它变成更具表现力的东西:

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;

我已将代码推送到gist

更新:我最近也blogged about this

更新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.

答案 1 :(得分:0)

你见过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&amp;许多数据类型原生。如果你想改变语法,它会附带一个鹿茸文件。还有一个支持MEF加载新功能的fork。