在实际开发中有时需要根据用户制定的公式然后经过处理并将数值代替参数后来得出此公式的值,因为刚好也做到这里,看了些资料,于是写了一个类调用来实现此功能
using System;
using System.Text;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.Reflection;
public class Evaluator {
object _compiled = null;
private string m_formula;
/// <summary>
/// 计算公式
/// </summary>
public string Formula{
get{
return m_formula;
}
set{
m_formula = value;
}
}
public Evaluator() {
}
public Evaluator(string formula){
Formula = formula;
}
public Double Execute(){
if(Formula == null || Formula == ""){
throw new Exception("请先设置Formula属性!");
}
return this.Execute(Formula);
}
public Double Execute(string formula){
constructEvaluator(formula);
MethodInfo m = _compiled.GetType().GetMethod("GetValue");
return (Double)m.Invoke(_compiled, null);
}
private void constructEvaluator(string formula) {
ICodeCompiler compiler = (new CSharpCodeProvider().CreateCompiler());
CompilerParameters cp = new CompilerParameters();
cp.ReferencedAssemblies.Add("system.dll");
cp.GenerateExecutable = false;
cp.GenerateInMemory = true;
StringBuilder str = new StringBuilder();
str.Append("using System; /n");
str.Append("namespace Stoway { /n");
str.Append("public class Formula { /n");
str.AppendFormat(" public {0} GetValue()","Double");
str.Append("{");
str.AppendFormat(" return Convert.ToDouble({0}); ", formula);
str.Append("}/n");
str.Append("}/n");
str.Append("}");
CompilerResults cr = compiler.CompileAssemblyFromSource(cp, str.ToString());
if (cr.Errors.HasErrors) {
throw new Exception("不是正确的表达式");
}
Assembly a = cr.CompiledAssembly;
_compiled = a.CreateInstance("Stoway.Formula");
}
public static Double GetValue(string formula){
return new Evaluator().Execute(formula);
}
}
-----------
调用方法:
Evaluator evaluator = new Evaluator();
Double num = evaluator.Execute("( 3 + 5 ) * 2 + 56 / 0.25");
也可以:
Double num = Evaluator.GetValue("( 3 + 5 ) * 2 + 56 / 0.25");
-------------------------------------------------------
相关:
http://www.codeproject.com/csharp/matheval.asp
http://www.codeproject.com/csharp/runtime_eval.asp