广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C# 实现Eval(字符串表达式)的三种方法
  • 451
分享到

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

2024-04-02 19:04:59 451人浏览 安东尼
摘要

目录一、背景二、代码三、测试一、背景 假如给定一个字符串表达式"-12 * ( - 2.2 + 7.7 ) - 44 * 2",让你计算结果,熟悉javascript的都知道有个E

一、背景

假如给定一个字符串表达式"-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(字符串表达式)的资料请关注编程网其它相关文章!

--结束END--

本文标题: C# 实现Eval(字符串表达式)的三种方法

本文链接: https://www.lsjlt.com/news/123325.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作