C# 实现Eval(字符串表达式)的三种方法

时间:2021-05-19

一、背景

假如给定一个字符串表达式"-12 * ( - 2.2 + 7.7 ) - 44 * 2",让你计算结果,熟悉JavaScript的都知道有个Eval函数可以直接进行计算,而C#中却没有这个函数,下面提供三种实现方式

二、代码

public class Class1 { #region 方法一:利用CodeCom [Obsolete] System.CodeDom.Compiler.ICodeCompiler comp = new Microsoft.CSharp.CSharpCodeProvider().CreateCompiler(); System.CodeDom.Compiler.CompilerParameters cp = new System.CodeDom.Compiler.CompilerParameters(); public object Eval_1(string Expression) { StringBuilder code = new StringBuilder(); code.Append("using System; \n"); code.Append("namespace ADOGuy { \n"); code.Append(" public class _Evaluator { \n"); code.Append(" public object __foo() "); code.Append("{ "); code.AppendFormat(" return ({0}); ", Expression); code.Append("}\n"); code.Append("} }"); System.CodeDom.Compiler.CompilerResults cr = comp.CompileAssemblyFromSource(cp, code.ToString()); System.Reflection.Assembly a = cr.CompiledAssembly; object _Compiled = a.CreateInstance("ADOGuy._Evaluator"); System.Reflection.MethodInfo mi = _Compiled.GetType().GetMethod("__foo"); return mi.Invoke(_Compiled, null); } #endregion #region 方法二:对表达式分析 string Precede(string p, string q) { switch (p) { case "+": case "-": return ("*/(".IndexOf(q) != -1) ? "<" : ">"; case "*": case "/": return (q == "(") ? "<" : ">"; case "(": return (q == ")") ? "=" : "<"; case ")": return (q == "(") ? "?" : ">"; case "#": return (q == "#") ? "=" : "<"; } return "?"; } Double Operate(Double a, char o, Double b) { switch (o) { case '+': return a + b; case '-': return a - b; case '*': return a * b; case '/': return a / b; } return 0; } public Object Eval_2(string Expression) { Stack nArr = new Stack(), oArr = new Stack(); int j = 0; Double a = 0, b = 0; string w = ""; char o; MatchCollection arr = Regex.Matches(Expression.Replace(" ", "") + "#", @"(((?<=(^|\())-)?\d+(\.\d+)?|\D)"); oArr.Push('#'); w = Convert.ToString(arr[j++]); while (!(w == "#" && Convert.ToString(oArr.Peek()) == "#")) { if ("+-*/()#".IndexOf(w) != -1) { switch (Precede(oArr.Peek().ToString(), w)) { case "<": oArr.Push(w); w = Convert.ToString(arr[j++]); break; case "=": oArr.Pop(); w = Convert.ToString(arr[j++]); break; case ">": o = Convert.ToChar(oArr.Pop()); b = Convert.ToDouble(nArr.Pop()); a = Convert.ToDouble(nArr.Pop()); nArr.Push(Operate(a, o, b)); break; default: return "Error"; } } else { nArr.Push(w); w = Convert.ToString(arr[j++]); } } return nArr.Pop(); } #endregion #region 方法三:利用JScript的Eval //需要引用Microsoft.JScript [Obsolete] readonly Microsoft.JScript.Vsa.VsaEngine ve = Microsoft.JScript.Vsa.VsaEngine.CreateEngine(); [Obsolete] public object Eval_3(string Expression) { return Microsoft.JScript.Eval.JScriptEvaluate(Expression, ve); } #endregion }

三、测试

static void Main(string[] args) { String strExpression = "-12 * ( - 2.2 + 7.7 ) - 44 * 2"; var obj = new Class1(); Console.WriteLine($"方法一(CodeCom法)计算结果:{obj.Eval_1(strExpression)}"); Console.WriteLine($"方法二(分析法)计算结果:{obj.Eval_2(strExpression)}"); Console.WriteLine($"方法三(JScript法)计算结果:{obj.Eval_3(strExpression)}"); Console.ReadLine(); }

运行结果:
方法一(CodeCom法)计算结果:-154
方法二(分析法)计算结果:-154
方法三(JScript法)计算结果:-154

以上就是C# 实现Eval(字符串表达式)的三种方法的详细内容,更多关于C# 实现Eval(字符串表达式)的资料请关注其它相关文章!

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章