概述
一、背景
假如给定一个字符串表达式"-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(字符串表达式)的资料请关注靠谱客其它相关文章!
最后
以上就是知性导师为你收集整理的C# 实现Eval(字符串表达式)的三种方法的全部内容,希望文章能够帮你解决C# 实现Eval(字符串表达式)的三种方法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复