C#编译数值表达式

C#编译数值表达式,c#,compilation,C#,Compilation,假设我允许用户输入一个任意数值表达式,该表达式允许使用显式函数集和预定义变量 解释这一点非常直截了当,但如果性能是一个关键因素呢 我需要一种方法(在运行时)将带有表达式的字符串编译成可以在变量上使用不同值执行20K次的内容。在C#4.0中,这将变得非常简单和直接。然而,在C#4.0之前,我建议您使用Microsoft.JScript库来完成它 这就是您想要的:所以您确实想要将字符串解析为(最终)类型化委托 一个选项是将字符串解析为表达式,然后将其编译为lambda。这是相当复杂的,但我有一些代码

假设我允许用户输入一个任意数值表达式,该表达式允许使用显式函数集和预定义变量

解释这一点非常直截了当,但如果性能是一个关键因素呢

我需要一种方法(在运行时)将带有表达式的字符串编译成可以在变量上使用不同值执行20K次的内容。

在C#4.0中,这将变得非常简单和直接。然而,在C#4.0之前,我建议您使用
Microsoft.JScript
库来完成它


这就是您想要的:

所以您确实想要将字符串解析为(最终)类型化委托

一个选项是将字符串解析为
表达式
,然后将其编译为lambda。这是相当复杂的,但我有一些代码可以完成大部分工作——但是可能已有的解析器已经完全完成了这项工作

作为一个简单的
表达式
示例:

    var x = Expression.Parameter(typeof(double), "x");
    var y = Expression.Parameter(typeof(double), "y");
    var body = Expression.Multiply(x, y);
    var func = Expression.Lambda<Func<double, double,double>>(body, x, y).Compile();

    double z = func(123.45, 678.90);
var x=Expression.Parameter(typeof(double),“x”);
变量y=表达式参数(typeof(double),“y”);
变量体=表达式。乘法(x,y);
var func=Expression.Lambda(body,x,y).Compile();
双z=func(123.45678.90);
问题是解析代码的其余部分-p

上周我给
表达式
解析器写了一个
字符串
,但它比我通常在这里发布的代码要多。。。超过300行(不包括对定制外部函数或命名参数的识别(目前使用匿名“?”占位符))


但是,如果(正如您所说)解释很容易,那么也许可以使用类似的代码编写一个可以编译的
表达式

微软的Linq示例已经包含可扩展Linq解析器的实现

sealed class Order
{
  public double SubTotal { get; set; }
  public double Shipping { get; set; }
}
static void Main()
{
  var calculateTotal = DynamicExpression
    .ParseLambda<Order, double>("SubTotal*@0+Shipping", 0.12)
    .Compile();

  var order = new Order
  {
    SubTotal = 124.99,
    Shipping = 7.99
  };
  Console.WriteLine(calculateTotal(order));
  Console.ReadLine();
}
密封类订单
{
公共双小计{get;set;}
公共双重传送{get;set;}
}
静态void Main()
{
var calculateTotal=动态表达式
.ParseLambda(“小计*@0+装运”,0.12)
.Compile();
var订单=新订单
{
小计=124.99,
航运=7.99
};
控制台写入线(计算总计(订单));
Console.ReadLine();
}

你可以查看来源或这篇文章了解更多详情:

@Mehrdad-我手头有大部分代码,我只是不确定这是不是最好的垃圾场。。。现有的解析器可能也存在。OP说“解释这个很直接”,所以这可能不是一个陌生的领域。是的,这肯定是更好的方法。JScript方式容易受到JS注入等危险因素的攻击。这看起来是我想要的解决方案,但性能呢?(解析并不容易,但这是一个很难找到示例源代码的常见问题,并不意味着要将其琐碎化:)一旦将其编译为委托,性能将非常非常快。本质上,好像已经编写了一个C#方法来执行“x+y*z/sin(x)”等,如果您需要解析器的帮助,请返回给我。。。我很容易找到原始表达式是如何定义的?也就是说,它是一根绳子吗?