假设我允许用户输入允许使用显式函数集和预定义变量的任意数值表达式。
解释这一点非常简单,但如果表现是一个关键因素呢?
我需要一种方法来编译(在运行时)带有表达式的字符串,这些字符串可以在变量上使用不同的值执行20K次。
答案 0 :(得分:2)
所以你真的要将字符串解析为(最终)一个类型化的委托。
一个选项,然后将字符串解析为Expression
,然后可以将其编译为lambda。这是非常复杂的,但是我有一些代码可以做很多事情 - 但是现有的解析器可能已经完全完成了这项工作。
作为一个微不足道的Expression
示例:
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);
问题是解析代码的其余部分;-p
我上周写了一个string
到Expression
解析器,但它的代码比我通常在这里发布的代码多......超过300行(不包括对定制外部函数的识别,或命名参数(它目前使用匿名的“?”占位符))。
但是如果(正如你所说)解释很容易,那么也许可以使用类似的代码编写一个你可以编译的Expression
?
答案 1 :(得分:2)
Microsoft的Linq Samples已经包含可扩展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();
}
您可以查看DbLinq project的来源或此帖子了解详情:Dynamic Linq and Expression Parsing in .NET as a hint of C# compiler extensibility
答案 2 :(得分:1)
在C#4.0中,它将变得非常简单和直接。但是,在C#4.0之前,我建议您使用Microsoft.JScript
库来完成它。