返回顶部

收藏

C#将字符串转换成表达式执行输出运算结果的代码

更多

C#将字符串转换成表达式执行输出运算结果的代码,比如有一个算术表达式的字符串"2*3+5",通过下面自定义的C#类可以直接传入字符串进行运算,输出结果11

调用方法

string exp = "80<=50?80:(80<=100?120:120+RoundUp(Math.round((80-100)/100,6),0) *40)";//Math.round()为jScript 里的方法,RoundUp为上面我定义的方法。

MessageBox.Show(Evaluator.Eval(exp).ToString());

using System;  
using System.Collections.Generic;  
using System.Text;  

using System.CodeDom.Compiler;//这个命名空间不要忘了  
using System.Reflection;  

namespace Common.Doing  
{  
    /// <summary>  
    /// 动态求值  
    /// </summary>  
    public class Evaluator  
    {  
        /// <summary>  
        /// 计算结果,如果表达式出错则抛出异常  
        /// </summary>  
        /// <param name="statement">表达式,如"1+2+3+4"</param>  
        /// <returns>结果</returns>  
        public static object Eval(string statement)  
        {  
            //调用实例化后的对象的方法,注意:第一个参数必须为JScript源代码里的方法。且所传字符串里的运算规则或方法也必须为JScript所支持  
            return _evaluatorType.InvokeMember(  
                        "Eval",  
                        BindingFlags.InvokeMethod,  
                        null,  
                        _evaluator,  
                        new object[] { statement }  
                     );  
        }  

        static Evaluator()  
        {  
            //构造JScript的编译驱动代码,该语言必须为.net支持的语言,根据语言名称驱动对应的编译器  
            CodeDomProvider provider = CodeDomProvider.CreateProvider("JScript");  
            //设置调用编译器的参数,下面参数设置编译器将程序集输出到内存。  
            CompilerParameters parameters;  
            parameters = new CompilerParameters();  
            parameters.GenerateInMemory = true;  
            //根据设置的编译器参数对语言源代码进行编译  
            CompilerResults results;  
            results = provider.CompileAssemblyFromSource(parameters, _jscriptSource);  
            //获取编译好的程序集  
            Assembly assembly = results.CompiledAssembly;  
            //获取程序集后,使用反射获取程序集中的类  
            _evaluatorType = assembly.GetType("Evaluator");  
            //创建获取到的类的实例  
            _evaluator = Activator.CreateInstance(_evaluatorType);  
        }  

        private static object _evaluator = null;  
        private static Type _evaluatorType = null;  

        /// <summary>  
        /// JScript语言源代码。即你想要被编译的源代码,这个代码里包含了字符串参数中方法或规则。  
        /// </summary>  
        private static readonly string _jscriptSource =  
            @" import SharpDll;  
                class Evaluator  
               {  
                   public function Eval(expr : String) : String   
                   {   
                      return eval(expr);   
                   }  
                public function RoundUp(numVar:double,len:int):double  
                {  //var dindex:int = numVar.ToString().IndexOf(" + "\\".\\"" + @");  
                   //return double.Parse(numVar.ToString().Substring(0,dindex))+ 1;  
                    var numRev:double = 0;  
                    var dindex:int = numVar.ToString().IndexOf("+"\\".\\""+ @");  
                    if (dindex> -1)  
                    {  
                        if (len == 0)  
                        {  
                            if (int.Parse(numVar.ToString().Substring(dindex+1))> 0)  
                            {  
                                numRev = double.Parse(numVar.ToString().Substring(0,dindex))+ 1;  
                            }  
                        }  
                        if (len > 0)  
                        {  
                            if ((dindex + len) > numVar.ToString().Substring(dindex).Length)  
                            {  
                                numRev = numVar;  
                            }  
                            else  
                            {  
                                if (int.Parse(numVar.ToString().Substring(dindex + len+1)) > 0)  
                                {  
                                    var tempnum:double = double.Parse(numVar.ToString().Substring(0,dindex+len+1)) * invokeIn(len)+1;  
                                    numRev = double.Parse(tempnum.ToString().Insert(tempnum.ToString().Length - len, " + "\\".\\"" + @"));  
                                }  
                                else   
                                {  
                                    numRev = double.Parse(numVar.ToString().Substring(0, dindex + len));  
                                }  
                            }  
                        }  
                    }  
                    else   
                    {  
                        numRev = numVar;  
                    }  
                    return numRev;  
                }  
                public function invokeInt(len:int):int  
                {  
                    var TempVal:String = "+"\\"1\\""+ @";  
                    var i:int = 0;  
                    while(i<len)   
                    {  
                        TempVal = TempVal+" + "\\"0\\"" + @";  
                        i++;  
                    }  
                    return int.Parse(TempVal);  
                }  
               }";  
    }  
}
//该片段来自于http://outofmemory.cn

标签:c#,.net,基础

收藏

0人收藏

支持

0

反对

0

相关聚客文章
  1. dormy 发表 2013-12-12 02:28:41 c#.netDataGrid绑定数据库数据
  2. K-Res 发表 2017-01-03 05:29:30 IAsyncOperation does not contain a definition for
  3. 汪宇杰 发表 2015-04-22 07:08:56 如何高逼格读取Web.config中的AppSettings
  4. Herb Sutter 发表 2013-07-09 16:47:02 Recommended reading: Why mobile web apps are slow
  5. itcodes 发表 2014-07-22 17:00:00 C#计算时间差。
  6. 姚 广远 发表 2015-06-22 07:01:45 C++ 中的封送处理概述
  7. 姚 广远 发表 2015-04-15 05:20:48 C#语言规范—语句
  8. zangw 发表 2015-01-21 11:32:10 Named pipe client throw UnauthorizedAccessExceptio
  9. 姚 广远 发表 2015-04-08 01:01:52 .NET逻辑分层架构总结
  10. 姚 广远 发表 2015-04-14 06:17:41 C# 语言规范 —类型、变量和值
  11. Herb Sutter 发表 2012-04-07 06:13:01 We want await! A C# talk that’s applicable to C++
  12. 姚 广远 发表 2015-04-13 05:03:47 .NET运行机制

发表评论