温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

C#实现Eval的方法有哪些

发布时间:2021-04-12 11:39:38 来源:亿速云 阅读:538 作者:小新 栏目:开发技术

小编给大家分享一下C#实现Eval的方法有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

一、背景

假如给定一个字符串表达式"-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的方法有哪些”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI