请问怎么才能让字符串变成语句执行,比如我有个字符串是"20+30+40",能让他返回90.

解决方案 »

  1.   

    计算表达式的问题ref:
    http://montaque.cnblogs.com/archive/2005/12/28/306407.html
    http://blog.joycode.com/ninputer/archive/2005/04/05/47003.aspx
      

  2.   

    <%@ Page language="c#" Codebehind="调用命令行编译器.aspx.cs" AutoEventWireup="false" Inherits="bsTest2005_8_16.Samples.调用命令行编译器" %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
    <HTML>
    <HEAD>
    <title>调用命令行编译器</title>
    <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
    <meta name="CODE_LANGUAGE" Content="C#">
    <meta name="vs_defaultClientScript" content="JavaScript">
    <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
    </HEAD>
    <body MS_POSITIONING="GridLayout">
    <form id="Form1" method="post" runat="server">
    <FONT face="宋体">
    <asp:TextBox id="TextBox1" style="Z-INDEX: 101; LEFT: 16px; POSITION: absolute; TOP: 184px" runat="server"
    Width="448px"></asp:TextBox>
    <asp:Button id="Button1" style="Z-INDEX: 102; LEFT: 480px; POSITION: absolute; TOP: 184px" runat="server"
    Text="Button"></asp:Button>&lt;
    <DIV style="DISPLAY: inline; Z-INDEX: 104; LEFT: 16px; WIDTH: 536px; POSITION: absolute; TOP: 128px; HEIGHT: 48px"
    ms_positioning="FlowLayout"><b>输入表达式,可输出结果。</b>
    <br>
    例如输入“100 + 41*0.5”,那么可以计算出结果120.5并输出。</DIV>
    </FONT>
    </form>
    </body>
    </HTML>
      

  3.   

    using System;
    using System.CodeDom.Compiler;
    using System.Reflection;
    using System.Text;
    using Microsoft.CSharp;namespace Expression
    {
        /// <summary>
        /// 计算表达式的类
        /// </summary>
        public class CalculateExpression
        {
            /// <summary>
            /// 接受一个string类型的表达式并计算结果,返回一个object对象,静态方法
            /// </summary>
            /// <param name="expression"></param>
            /// <returns></returns>
            public static object Calculate(string expression)
            {
                string className = "Calc";
                string methodName = "Run";
                expression = expression.Replace("/", "*1.0/");            // 创建编译器实例。 
                CodeDomProvider complier = (new Microsoft.CSharp.CSharpCodeProvider());
                // 设置编译参数。 
                CompilerParameters paras = new CompilerParameters();
                paras.GenerateExecutable = false;
                paras.GenerateInMemory = true;            // 创建动态代码。 
                StringBuilder classSource = new StringBuilder();
                classSource.Append("public class " + className + "\n");
                classSource.Append("{\n");
                classSource.Append("    public object " + methodName + "()\n");
                classSource.Append("    {\n");
                classSource.Append("        return " + expression + ";\n");
                classSource.Append("    }\n");
                classSource.Append("}");            // 编译代码。 
                CompilerResults result = complier.CompileAssemblyFromSource(paras, classSource.ToString());            // 获取编译后的程序集。 
                Assembly assembly = result.CompiledAssembly;            // 动态调用方法。 
                object eval = assembly.CreateInstance(className);
                MethodInfo method = eval.GetType().GetMethod(methodName);
                object reobj = method.Invoke(eval, null);
                GC.Collect();
                return reobj;
            }
        }
    }
      

  4.   

    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Web;
    using System.Web.SessionState;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.HtmlControls;namespace bsTest2005_8_16.Samples
    {
    /// <summary>
    /// 调用命令行编译器 的摘要说明。
    /// </summary>
    public class 调用命令行编译器 : System.Web.UI.Page
    {
            protected System.Web.UI.WebControls.TextBox TextBox1;
            protected System.Web.UI.WebControls.Button Button1;
        
    private void Page_Load(object sender, System.EventArgs e)
    {
    // 在此处放置用户代码以初始化页面
    }        private object GetJedgement(string expression)
            {
                    
                Microsoft.CSharp.CSharpCodeProvider provider = new Microsoft.CSharp.CSharpCodeProvider();            System.CodeDom.Compiler.ICodeCompiler comp = provider.CreateCompiler();            System.CodeDom.Compiler.CompilerParameters cp = new System.CodeDom.Compiler.CompilerParameters();            cp.ReferencedAssemblies.Add("system.dll")  ;
                cp.ReferencedAssemblies.Add("system.data.dll")  ;
                cp.ReferencedAssemblies.Add("system.xml.dll")  ;
                cp.GenerateExecutable  =  false  ;
                cp.GenerateInMemory  =  true  ;            string code = @"using System;  
                                using System.Data;    
                                using System.Xml;       
                                public  class Judgement
                                {         
                                     public  object  GetJude()
                                     {    
                                          return  ("  +  expression  +  @");    
                                     }    
                                }" ; 
                System.CodeDom.Compiler.CompilerResults cr = comp.CompileAssemblyFromSource(cp,code);
                System.Diagnostics.Debug.Write(code);            if(cr.Errors.HasErrors)
                {
                    System.Text.StringBuilder errorMsg = new System.Text.StringBuilder();
                   
                    foreach(System.CodeDom.Compiler.CompilerError err in cr.Errors)
                    {
                        errorMsg.Append(err.ErrorText );
                    }
                    System.Diagnostics.Debug.WriteLine(errorMsg.ToString());
                   
                    throw new System.Exception("编译错误:  "  +  errorMsg.ToString()); 
                    //return false;
                }
                else
                {
                    System.Reflection.Assembly  tmp = cr.CompiledAssembly;
                    object _Compiled  =  tmp.CreateInstance("Judgement");
                    System.Reflection.MethodInfo mi = _Compiled.GetType().GetMethod("GetJude"); 
                    
                    return mi.Invoke(_Compiled,null);
                }
                        }
            
            private void Button1_Click(object sender, System.EventArgs e)
            {
                string tmp = this.TextBox1.Text;
                Response.Write(this.GetJedgement(tmp).ToString());
            }
    #region Web 窗体设计器生成的代码
    override protected void OnInit(EventArgs e)
    {
    //
    // CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
    //
    InitializeComponent();
    base.OnInit(e);
    }

    /// <summary>
    /// 设计器支持所需的方法 - 不要使用代码编辑器修改
    /// 此方法的内容。
    /// </summary>
    private void InitializeComponent()
    {    
                this.Button1.Click += new System.EventHandler(this.Button1_Click);
                this.Load += new System.EventHandler(this.Page_Load);        }
    #endregion      
    }
    }
      

  5.   

    该类的Calculate方法接收一个字符串计算并返回一个object类型的结果。原理大概是利用编译器对接收的字符串重新编译。可计算各种字符串格式的表达式。如"1+1","10>2","10>2 && 10<2"
      

  6.   

    很多人会说语言只是语法的差异,事实上,大家忽略了一点选择了一种语言,语言的提供者一定会提供很多的系统库给这个语言. 接下来一个简单的例子来结合Jscript.net 和 C# 来实现对一个表达式的计算.问题要求: 输入一串简单的表达式,输出值.
    比如2+4*7 返回30注意我们全部用.net 去实现,呵呵. 1.新建一个jscript文件, CustomEval.js// JScript source code
    class CustomEval
    {
    static function eval(strExp)
    {
    return eval(strExp);
    }}然后到.net 的command prompt,编译该js为一个.net 程序集jsc /t:library CustomEval.js
    然后就生成了一个CustomEval.dll 标准的.net程序集. 调用也很简单. 
    新建一个项目,引用该dll, 并且也引用MIcrosoft.Jscript.dll如下代码: class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine(CustomEval.eval("2+4*7"));
            }
        }
    呵呵,结果就出来了. 类似你用C# 可以用很多Microsoft.Visualbasic.*.dll 提供的功能. C# 利用VB的特性
      

  7.   

    动态计算字串表达式值的类 
    最近用到了这个功能,要计算一些字符串表达式,如"1 + 3 / 2"等等,就写了这个类。原理很简单,就是用CodeDom动态生成一个包含自定义函数的程序集,再通过反射调用。网上例子极多。我这个类是拿来就可以用的,只需要Copy一下代码就可以直接用,不用读代码。支持常用数学函数,如Sin,Log等,而且不区分大小写。using System;
    using System.Collections.Generic;
    using System.Text;
    using System.CodeDom.Compiler;
    using Microsoft.VisualBasic;
    using System.Reflection;namespace Ninputer.Utilities
    ...{
        sealed class Evaluator
        ...{
            private static CodeDomProvider comp = new VBCodeProvider();
            private static CompilerParameters cp = new CompilerParameters();
            private static MethodInfo mi;        public static object Eval(string expression)
            ...{
                StringBuilder codeBuilder = new StringBuilder();            codeBuilder.AppendLine("Imports System");
                codeBuilder.AppendLine("Imports System.Math");
                codeBuilder.AppendLine("Imports Microsoft.VisualBasic");
                codeBuilder.AppendLine();
                codeBuilder.AppendLine("Public Module Mode");
                codeBuilder.AppendLine("   Public Function Func() As Object");
                codeBuilder.AppendLine("        Return " + expression);
                codeBuilder.AppendLine("   End Function");
                codeBuilder.AppendLine("End Module");            cp.ReferencedAssemblies.Add("System.dll");
                cp.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll");
                cp.GenerateExecutable = false;
                cp.GenerateInMemory = true;            string code = codeBuilder.ToString();
                CompilerResults cr = comp.CompileAssemblyFromSource(cp, code);            if (cr.Errors.HasErrors)
                ...{
                    return null;
                }
                else
                ...{
                    Assembly a = cr.CompiledAssembly;
                    Type t = a.GetType("Mode");
                    //object mode = a.CreateInstance("Mode");
                    mi = t.GetMethod("Func", BindingFlags.Static | BindingFlags.Public);
                    return mi.Invoke(null, new object[0]);
                }
            }
        }
    }用法也非常简单,实际上除了数学表达式,任何含字面量的有效VB表达式都可以执行。class Program
    ...{
        static void Main(string[] args)
        ...{
            double a = (double)Evaluator.Eval("sin(0.2) + 5");
            Console.WriteLine(a.ToString());
        }
    }
    注意,我使用的是.NET 2.0的语法,使用.NET 1.1 / VS.NET 2003的请用这段代码:using System;
    using System.Text;
    using System.CodeDom.Compiler;
    using Microsoft.VisualBasic;
    using System.Reflection;namespace Ninputer.Utilities
    {
    sealed class Evaluator
    {
    private static CodeDomProvider comp = new VBCodeProvider();
    private static CompilerParameters cp = new CompilerParameters();
    private static MethodInfo mi; public static object Eval(string expression)
    {
    StringBuilder codeBuilder = new StringBuilder(); codeBuilder.AppendLine("Imports System");
    codeBuilder.AppendLine("Imports System.Math");
    codeBuilder.AppendLine("Imports Microsoft.VisualBasic");
    codeBuilder.AppendLine();
    codeBuilder.AppendLine("Public Module Mode");
    codeBuilder.AppendLine("   Public Function Func() As Object");
    codeBuilder.AppendLine("        Return " + expression);
    codeBuilder.AppendLine("   End Function");
    codeBuilder.AppendLine("End Module"); cp.ReferencedAssemblies.Add("System.dll");
    cp.ReferencedAssemblies.Add("Microsoft.VisualBasic.dll");
    cp.GenerateExecutable = false;
    cp.GenerateInMemory = true; string code = codeBuilder.ToString();
    CompilerResults cr = comp.CreateCompiler().CompileAssemblyFromSource(cp, code); if (cr.Errors.HasErrors)
    {
    return null;
    }
    else
    {
    Assembly a = cr.CompiledAssembly;
    Type t = a.GetType("Mode");
    //object mode = a.CreateInstance("Mode");
    mi = t.GetMethod("Func", BindingFlags.Static | BindingFlags.Public);
    return mi.Invoke(null, new object[0]);
    }
    }
    }
    }
      

  8.   

    还有更好的方法 
    Microsoft.JScript.Vsa.VsaEngine ve=Microsoft.JScript.Vsa.VsaEngine.CreateEngine(); 
    object qswhEval3(string Expression){ 
    return Microsoft.JScript.Eval.JScriptEvaluate(Expression,ve); 
    } 只需要添加Microsoft.JScript和Microsoft.Vsa两个引用就OK,超简洁....呵呵 ====public static object Eval(string expression) 

    System.Data.DataTable table=new System.Data.DataTable(); 
    System.Data.DataColumn Col=new System.Data.DataColumn("col1",typeof(string),expression); 
    table.Columns.Add(Col); table.Rows.Add(new object[] {""}); 
    return table.Rows[0][0]; 

    ===
    这样做不错,但是搂住没有考虑到一个问题,每做一次计算,就会编译出来一个Assembly,并装载在当前的AppDomain,这样随着程序的不断计算,越来越多地Assembly被装载在当前AppDomain,一个Assembly一旦被装载,除非所在的AppDomain被卸载,否则。net是不能单独卸载某个Assembly,这样使用的内存会越来越多,又不能被垃圾回收 ===
    最简单的方法: 
    string exp = "(5+6)*8-3/2-4+3"; 
    DataTable myDataTable = new DataTable("CalcTable"); 
    exp = Convert.ToString(myDataTable.Compute(exp,"")); 
    ===
      

  9.   

    全是在风满袖给的URL中看到的。唉,为什么,不多用网络于学习呢?其实在二楼,此问题就已经解决了。如果能善用google.com baidu.com的话,根本不用问这种问题。
      

  10.   

    最简单的方法: 
    string exp = "(5+6)*8-3/2-4+3"; 
    DataTable myDataTable = new DataTable("CalcTable"); 
    exp = Convert.ToString(myDataTable.Compute(exp,"")); 
    ===牛啊!