达斯维达!
这里有几个选项,这取决于您的需求以及您是需要一些非常复杂的东西还是需要一些简单易懂和扩展的东西(可能是出于学术目的)。
1) 让我们从简单、容易和可定制的开始。我创建了一个满足您在帖子中指定的需求的类,但是它非常原始,不应该在没有进一步测试和修改的情况下用于商业项目......如果你可以轻松地拿起它并增加它想要...它显示了一种简单的方法来实现您所需要的。该代码运行良好,但没有考虑数学优先级(例如括号或 * over +)。为了做到这一点,它需要进行调整......
代码如下,它被注释并希望自我解释:
public class DynamicFormula
{
/// <summary>
/// This simply stores a variable name and its value so when this key is found in a expression it gets the value accordingly.
/// </summary>
public Dictionary<string, double> Variables { get; private set; }
/// <summary>
/// The expression itself, each value and operation must be separated with SPACES. The expression does not support PARENTHESES at this point.
/// </summary>
public string Expression { get; set; }
public DynamicFormula()
{
this.Variables = new Dictionary<string, double>();
}
public double CalculateResult()
{
if (string.IsNullOrWhiteSpace(this.Expression))
throw new Exception("An expression must be defined in the Expression property.");
double? result = null;
string operation = string.Empty;
//This will be necessary for priorities operations such as parentheses, etc... It is not being used at this point.
List<double> aux = new List<double>();
foreach (var lexema in Expression.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries))
{
//If it is an operator
if (lexema == "*" || lexema == "/" || lexema == "+" || lexema == "-")
{
operation = lexema;
}
else //It is a number or a variable
{
double value = double.MinValue;
if (Variables.ContainsKey(lexema.ToLower())) //If it is a variable, let's get the variable value
value = Variables[lexema.ToLower()];
else //It is just a number, let's just parse
value = double.Parse(lexema);
if (!result.HasValue) //No value has been assigned yet
{
result = value;
}
else
{
switch (operation) //Let's check the operation we should perform
{
case "*":
result = result.Value * value;
break;
case "/":
result = result.Value / value;
break;
case "+":
result = result.Value + value;
break;
case "-":
result = result.Value - value;
break;
default:
throw new Exception("The expression is not properly formatted.");
}
}
}
}
if (result.HasValue)
return result.Value;
else
throw new Exception("The operation could not be completed, a result was not obtained.");
}
/// <summary>
/// Add variables to the dynamic math formula. The variable should be properly declared.
/// </summary>
/// <param name="variableDeclaration">Should be declared as "VariableName=VALUE" without spaces</param>
public void AddVariable(string variableDeclaration)
{
if (!string.IsNullOrWhiteSpace(variableDeclaration))
{
var variable = variableDeclaration.ToLower().Split('='); //Let's make sure the variable's name is LOWER case and then get its name/value
string variableName = variable[0];
double variableValue = 0;
if (double.TryParse(variable[1], out variableValue))
this.Variables.Add(variableName, variableValue);
else
throw new ArgumentException("Variable value is not a number");
}
else
{
//Could throw an exception... or just ignore as it not important...
}
}
}
这是在 WPF 应用程序中使用上述类的示例(可用于任何 C# 应用程序)
private void btCalculate_Click(object sender, RoutedEventArgs e)
{
string expression = tboxExpression.Text; //"cost * item / 100" (IT MUST BE SEPARATED WITH SPACES!)
string variable1 = tboxVariable1.Text; //"item=10"
string variable2 = tboxVariable2.Text; //"cost=2.5"
DynamicFormula math = new DynamicFormula();
math.Expression = expression; //Let's define the expression
math.AddVariable(variable1); //Let's add the first variable
math.AddVariable(variable2); //Let's add the second variable
try
{
double result = math.CalculateResult(); //In this scenario the result is 0,25... cost * item / 100 = (2.5 * 10 / 100) = 0,25
//Console.WriteLine("Success: " + result);
tboxResult.Text = result.ToString();
}
catch(Exception ex)
{
//Console.WriteLine(ex.Message);
tboxResult.Text = ex.Message;
}
}
2) 如果您需要更强大的功能并且适用于大多数现实生活中的情况,您应该明确地检查一下 FLEE:
http://flee.codeplex.com/wikipage?title=Examples&referringTitle=Home
这是一个专门为此而设计的库,它支持多种公式!
查看一些示例并了解其工作原理可能需要一些时间,但它应该无需太多工作即可完成工作。
希望对你有帮助,
路易斯·恩里克·戈尔。