16,554
社区成员
发帖
与我相关
我的任务
分享
using System.CodeDom;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.Text;
using System.Reflection;
public class Evaluator
{
object _compiled = null;
/// <summary>
/// 计算公式
/// </summary>
public Evaluator()
{
}
private bool constructEvaluator(string formula, Type returnType)
{
string strTypeName = returnType.Name;
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 Boffin.Windows.Controls { \n");
str.Append("public class Formula { \n");
str.AppendFormat(" public {0} GetValue()", strTypeName);
str.Append("{");
str.AppendFormat(" return Convert.To" + strTypeName + "({0}); ", formula);
str.Append("}\n");
str.Append("}\n");
str.Append("}");
CompilerResults cr = compiler.CompileAssemblyFromSource(cp, str.ToString());
if (cr.Errors.HasErrors)
{
return false;
}
Assembly a = cr.CompiledAssembly;
_compiled = a.CreateInstance("Boffin.Windows.Controls.Formula");
return true;
}
public double ExecuteToDouble(string formula)
{
if (constructEvaluator(formula, typeof(double)) == false)
throw new Exception("计算\"" + formula + "\"表达式错误!");
MethodInfo m = _compiled.GetType().GetMethod("GetValue");
return (Double)m.Invoke(_compiled, null);
}
public static double GetDoubleValue(string formula)
{
return new Evaluator().ExecuteToDouble(formula);
}
public float ExecuteToSingle(string formula)
{
if (constructEvaluator(formula, typeof(float)) == false)
throw new Exception("计算\"" + formula + "\"表达式错误!");
MethodInfo m = _compiled.GetType().GetMethod("GetValue");
return (float)m.Invoke(_compiled, null);
}
public static Single GetSingleValue(string formula)
{
return new Evaluator().ExecuteToSingle(formula);
}
public Decimal ExecuteToDecimal(string formula)
{
if (constructEvaluator(formula, typeof(Decimal)) == false)
throw new Exception("计算\"" + formula + "\"表达式错误!");
MethodInfo m = _compiled.GetType().GetMethod("GetValue");
return (Decimal)m.Invoke(_compiled, null);
}
public static Decimal GetDecimalValue(string formula)
{
return new Evaluator().ExecuteToDecimal(formula);
}
public bool ExecuteToBoolean(string formula)
{
if (constructEvaluator(formula, typeof(bool)) == false)
throw new Exception("计算\"" + formula + "\"表达式错误!");
MethodInfo m = _compiled.GetType().GetMethod("GetValue");
return (bool)m.Invoke(_compiled, null);
}
public static bool GetBooleanValue(string formula)
{
return new Evaluator().ExecuteToBoolean(formula);
}
public Int16 ExecuteToInt16(string formula)
{
if (constructEvaluator(formula, typeof(Int16)) == false)
throw new Exception("计算\"" + formula + "\"表达式错误!");
MethodInfo m = _compiled.GetType().GetMethod("GetValue");
return (Int16)m.Invoke(_compiled, null);
}
public static Int16 GetInt16Value(string formula)
{
return new Evaluator().ExecuteToInt16(formula);
}
public Int32 ExecuteToInt32(string formula)
{
if (constructEvaluator(formula, typeof(Int32)) == false)
throw new Exception("计算\"" + formula + "\"表达式错误!");
MethodInfo m = _compiled.GetType().GetMethod("GetValue");
return (Int32)m.Invoke(_compiled, null);
}
public static Int32 GetInt32Value(string formula)
{
return new Evaluator().ExecuteToInt32(formula);
}
public Int64 ExecuteToInt64(string formula)
{
if (constructEvaluator(formula, typeof(Int64)) == false)
throw new Exception("计算\"" + formula + "\"表达式错误!");
MethodInfo m = _compiled.GetType().GetMethod("GetValue");
return (Int64)m.Invoke(_compiled, null);
}
public static Int64 GetInt64Value(string formula)
{
return new Evaluator().ExecuteToInt64(formula);
}
}
//测试
Console.WriteLine(Evaluator.GetDoubleValue("Math.Sin(12.23)+Math.Cos(15.2)"));
Console.WriteLine(Evaluator.GetInt16Value("12.23+15.2"));
Console.WriteLine(Evaluator.GetInt32Value("12.23+15.2"));
Console.WriteLine(Evaluator.GetInt64Value("12.23+15.2"));
Console.WriteLine(Evaluator.GetBooleanValue("12.23+15.2>10.3"));
Console.WriteLine(Evaluator.GetSingleValue("12.23+15.2"));