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; } } }
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;
http://montaque.cnblogs.com/archive/2005/12/28/306407.html
http://blog.joycode.com/ninputer/archive/2005/04/05/47003.aspx
<!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><
<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>
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;
}
}
}
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
}
}
比如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的特性
最近用到了这个功能,要计算一些字符串表达式,如"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]);
}
}
}
}
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,""));
===
string exp = "(5+6)*8-3/2-4+3";
DataTable myDataTable = new DataTable("CalcTable");
exp = Convert.ToString(myDataTable.Compute(exp,""));
===牛啊!