【发布时间】:2015-05-21 22:39:15
【问题描述】:
我对 Expressions 有一些乐趣,然后出现了一个问题:它引发了一个我没想到的异常。
我有一个输入 - 简单的数学公式,例如 2*x+3,我想为它创建一个表达式树。所以我写了这段代码
using System;
using System.Linq.Expressions;
namespace ConsoleApplication50
{
class Program
{
static void Main()
{
string s = "3*x^2+2/5*x+4";
Expression<Func<double, double>> expr = MathExpressionGenerator.GetExpression(s);
Console.WriteLine(expr);
var del = expr.Compile();
Console.WriteLine(del(10));
}
}
static class MathExpressionGenerator
{
public const string SupportedOps = "+-*/^";
private static readonly ParameterExpression Parameter = Expression.Parameter(typeof(double), "x");
public static Expression<Func<double, double>> GetExpression(string s)
{
ParameterExpression parameterExpression = Expression.Parameter(typeof(double), "x");
Expression result = GetExpressionInternal(s);
return Expression.Lambda<Func<double, double>>(result, parameterExpression);
}
private static Expression GetExpressionInternal(string s)
{
double constant;
if (s == "x")
return Parameter;
if (double.TryParse(s, out constant))
return Expression.Constant(constant, typeof(double));
foreach (char op in SupportedOps)
{
var split = s.Split(new[] { op }, StringSplitOptions.RemoveEmptyEntries);
if (split.Length > 1)
{
var expression = GetExpressionInternal(split[0]);
for (int i = 1; i < split.Length; i++)
{
expression = RunOp(expression, GetExpressionInternal(split[i]), op);
}
return expression;
}
}
throw new NotImplementedException("never throws");
}
private static Expression RunOp(Expression a, Expression b, char op)
{
switch (op)
{
case '+':
return Expression.Add(a, b);
case '-':
return Expression.Subtract(a, b);
case '/':
return Expression.Divide(a, b);
case '*':
return Expression.Multiply(a, b);
case '^':
return Expression.Power(a, b);
}
throw new NotSupportedException();
}
}
}
但我得到一个错误:
未处理的异常:System.InvalidOperationException:变量“x” 从范围“”引用的类型“System.Double”,但未定义 在 System.Linq.Expressions.Compiler.VariableBinder.Reference(ParameterExpress 离子节点,VariableStorageKind 存储)在 System.Linq.Expressions.Compiler.VariableBinder.VisitParameter(ParameterEx 压节点)在 System.Linq.Expressions.ParameterExpression.Accept(ExpressionVisitor 访问或)在...等等
请教,如何解决?在这里,我有一个全局参数并引用它,所以我不知道为什么它会这么说。
【问题讨论】:
标签: c# .net expression .net-4.5 expression-trees