0

我目前正在使用 ncalc 库进行多次评估并从中获得结果。

现在我发现了一个问题,如果我有一个格式为“1,234.01”的价格,它将无法评估我的表达式。

我使用的当前解决方法是删除,,但我想知道是否有办法评估货币而不必删除,例如:

decimal price = 0;
if (!decimal.TryParse(iPrice.Text, out price))
{
    MessageBox.Show("Price is not formatted correctly...");
    return;
}

decimal currency = 0;
if (!decimal.TryParse(iCurrency.Text, out currency))
{
    MessageBox.Show("Currency is not formatted correctly...");
    return;
}

string formula = iFormula.Text.Replace("Price", price.ToString("n2")).Replace("Currency", currency.ToString("n2"));
Expression exp = new Expression(formula);
exp.Evaluate();

评估失败是因为,我的价格,如果我删除它,它工作得很好。

公式示例:

(((Price+12,9)+((Price+12,9)*0,05)+(((Price+12,9)+((Price+12,9)*0,05))*0,029)+0,45)*Currency)

根据要求进行堆栈跟踪:

NCalc.EvaluationException was unhandled
  Message=mismatched input ',' expecting ')' at line 1:4
mismatched input ',' expecting ')' at line 1:20
mismatched input ',' expecting ')' at line 1:43
mismatched input ',' expecting ')' at line 1:59
missing EOF at ')' at line 1:77
  Source=NCalc
  StackTrace:
       at NCalc.Expression.Evaluate()
4

2 回答 2

2

我仍然不清楚您的问题,但我怀疑您可以通过更改替换时使用的格式来解决此问题。改变这个:

string formula = iFormula.Text.Replace("Price", price.ToString("n2")) 
                              .Replace("Currency", currency.ToString("n2"));

对此:

string formula = iFormula.Text.Replace("Price", price.ToString("f2")) 
                              .Replace("Currency", currency.ToString("f2"));

这将使用“定点”格式而不是“数字”格式。你不会得到分组。请注意,分组不是数字本身的一部分 - 它是您格式化数字的一部分。

顺便说一句,我也很想明确指定不变的文化。

顺便说一句:我自己没有使用过 NCalc,但如果它真的迫使您将表达式中的数值指定为text,那听起来很糟糕。我期望某种参数化(例如,根据大多数 SQL 提供程序)应该会使所有这些都消失。

于 2012-07-02T06:21:23.687 回答
0

不,您的十进制文字中不能有分隔符。编译器会将其与声明多个具有相同类型的变量混淆,例如:

decimal price = 1m, tax = 234m; 

但是,如果它是一个字符串,您可以像这样解析它:

decimal price = Decimal.Parse("1,234.0", CultureInfo.InvariantCulture); 

编辑:我上面的答案是针对问题的第一个版本中的代码示例。现在问题已被编辑:

您可以使用Decimal.ToString(string format, IFormatProvider provider)方法重载来控制十进制值的字符串表示。这允许您指定标准自定义格式字符串。在您的情况下,听起来您需要使用点分隔 2 个十进制数字,并且没有组分隔符(没有逗号)。所以你可以说:

price.ToString("F2", CultureInfo.InvariantCulture) // ex. result: "1234.56"

CultureInfo.InvariantCulture如果无论当前文化如何都需要点分隔符,这一点很重要。如果您不指定,则输出可能是“1234,56”,具体取决于当前文化(例如,在 de-DE 或 fr-FR 等欧洲文化的情况下)。

于 2012-07-02T05:53:43.893 回答