我有一些有趣的表現形式和出現的問題創建表達式:它拋出,我沒有想例外。一個簡單的數學公式
我有一個輸入 - 簡單的數學公式,例如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();
}
}
}
,但我得到一個錯誤:
Unhandled Exception: System.InvalidOperationException: variable 'x' of type 'Sys tem.Double' referenced from scope '', but it is not defined at System.Linq.Expressions.Compiler.VariableBinder.Reference(ParameterExpress ion node, VariableStorageKind storage) at System.Linq.Expressions.Compiler.VariableBinder.VisitParameter(ParameterEx pression node) at System.Linq.Expressions.ParameterExpression.Accept(ExpressionVisitor visit or) at ... and so on
請,諮詢,怎麼能解決嗎?在這裏我有一個單一的全局參數,並引用它,所以我不知道,爲什麼它說這個東西。
哎呀我的複製粘貼,我沒有」 t引用單個對象。這顯然是造成這種行爲的原因。感謝您的幫助 –
@AlexZhukovskiy:我用你的代碼,它的偉大工程用簡單的公式,但如何擴展代碼來支持括號:'()'和''e' Math.Expr'。我嘗試過,但我只得到例外 –
@PaulMeems這並不容易,使其與括號工作,因爲他們正在改變優先級,而我只是用'string.Split'而忽略它分裂。你基本上必須從頭開始重寫它。你可以嘗試首先打開括號(從3 *(x + 2)轉換到3 * x + 3 * 2,然後運行這個人。這可能比編寫嚴肅的解析器容易。 –