动态计算字符串表达式的结果
有没有办法计算字符串表达式的结果,例如mystring = "2*a+32-Math.Sin(6)"
动态地知道a是我拥有的变量,可能有一些动态解决方案或者使用System.Reflection
string mystring = "2*a+32-Math.Sin(6)"`; decimal result = SomeMethod(mystring,3); // where a = 3 for example
如何让javascript计算你的表达式?
Type scriptType = Type.GetTypeFromCLSID(Guid.Parse("0E59F1D5-1FBE-11D0-8FF2-00A0D10038BC")); dynamic obj = Activator.CreateInstance(scriptType, false); obj.Language = "javascript"; var res = obj.Eval("a=3; 2*a+32-Math.sin(6)");
您可以通过以下方式在SomeMethod
中使用数据表的计算方法:
static decimal Somemethod(int val) { var result = (decimal)new DataTable().Compute(string.Format("2*{0}+32-{1}", val, Math.Sin(6)), ""); return result; }
简单地说,您可以这样打电话:
result = Somemethod(3);
如果发现它的工作完美,抱歉打扰,我想要的就是动态编译器。 这就是我得到的
MessageBox.Show(Eval("5*3-Math.Sin(12) + 25*Math.Pow(3,2)").ToString()); public static object Eval(string sCSCode) { CodeDomProvider icc = CodeDomProvider.CreateProvider("C#"); CompilerParameters cp = new CompilerParameters(); cp.ReferencedAssemblies.Add("system.dll"); cp.ReferencedAssemblies.Add("system.xml.dll"); cp.ReferencedAssemblies.Add("system.data.dll"); cp.ReferencedAssemblies.Add("system.windows.forms.dll"); cp.ReferencedAssemblies.Add("system.drawing.dll"); cp.CompilerOptions = "/t:library"; cp.GenerateInMemory = true; StringBuilder sb = new StringBuilder(""); sb.Append("using System;n"); sb.Append("using System.Xml;n"); sb.Append("using System.Data;n"); sb.Append("using System.Data.SqlClient;n"); sb.Append("using System.Windows.Forms;n"); sb.Append("using System.Drawing;n"); sb.Append("namespace CSCodeEvaler{ n"); sb.Append("public class CSCodeEvaler{ n"); sb.Append("public object EvalCode(){n"); sb.Append("return " + sCSCode + "; n"); sb.Append("} n"); sb.Append("} n"); sb.Append("}n"); CompilerResults cr = icc.CompileAssemblyFromSource(cp, sb.ToString()); if (cr.Errors.Count > 0) { MessageBox.Show("ERROR: " + cr.Errors[0].ErrorText, "Error evaluating cs code", MessageBoxButton.OK, MessageBoxImage.Error); return null; } System.Reflection.Assembly a = cr.CompiledAssembly; object o = a.CreateInstance("CSCodeEvaler.CSCodeEvaler"); Type t = o.GetType(); System.Reflection.MethodInfo mi = t.GetMethod("EvalCode"); object s = mi.Invoke(o, null); return s; }
我不认为有任何本地支持你所要求的,但是有很多方法可以实现它,其中没有一个是完全无关紧要的,但按照我认为它们很简单的顺序:
使用要用于评估表达式的方法创建抽象类。 在运行时创建一个inheritance该类的新类。 我将很快分享这些代码。
正如这里所承诺的那样是代码:
public class BaseClass { public BaseClass(){} public virtual double Eval(double x,double y){return 0;} } public class MathExpressionParser { private BaseClass Evalulator=null; public MathExpressionParser(){} public bool Intialize(string equation) { Microsoft.CSharp.CSharpCodeProvider cp=new Microsoft.CSharp.CSharpCodeProvider(); System.CodeDom.Compiler.ICodeCompiler comp=cp.CreateCompiler(); System.CodeDom.Compiler.CompilerParameters cpar=new CompilerParameters(); cpar.GenerateInMemory=true; cpar.GenerateExecutable=false; cpar.ReferencedAssemblies.Add("system.dll"); cpar.ReferencedAssemblies.Add("EquationsParser.exe"); //Did you see this before; string sourceCode="using System;"+ "class DrivedEval:EquationsParser.BaseClass" + "{"+ "public DrivedEval(){}"+ "public override double Eval(double x,double y)"+ "{"+ "return "+ /*Looook here code insertion*/ equation +";"+ "}"+ "}"; //the previouse source code will be compiled now(run time); CompilerResults result=comp.CompileAssemblyFromSource(cpar,sourceCode); //If there are error in the code display it for the programmer who enter the equation string errors=""; foreach(CompilerError rrr in result.Errors) { if(rrr.IsWarning) continue; errors+="n"+rrr.ErrorText; errors+="n"+rrr.ToString(); } //You Can show error if there in the sourceCode you just compiled uncomment the following //MessageBox.Show(errors); if(result.Errors.Count==0&&result.CompiledAssembly!=null) { Type objtype=result.CompiledAssembly.GetType("DrivedEval"); try { if(objtype!=null) { Evalulator=(BaseClass)Activator.CreateInstance(objtype); } } catch(Exception ex) { MessageBox.Show(ex.Message,"Error in Creation the object"); } return true; } else return false; } public double evaluate(double x,double y) { if(Evalulator==null) return 0.0; return this.Evalulator.Eval(x,y); } }
并且您需要执行以下简单测试以确保其有效:
private void button1_Click(object sender, System.EventArgs e) { if(parser.Intialize(textBox1.Text)==false) { MessageBox.Show("Check equation"); return; } textBox4.Text=(parser.evaluate(double.Parse(textBox2.Text),double.Parse(textBox3.Text))).ToString(); }
以下是我在C#中动态评估字符串表达式时最常用的一些方法。
上述就是C#学习教程:动态计算字符串表达式的结果分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)
Microsoft解决方案
非Microsoft解决方案(并不是说有什么问题)
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请点击右边联系管理员删除。
如若转载,请注明出处:https://www.ctvol.com/cdevelopment/989446.html