如果想发较大的信件,请用Ninputer @ gmail.com
不要在我的Blog评论中张贴广告,除非同意向我付款。
最近用到了这个功能,要计算一些字符串表达式,如"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]); } } } }
打印 | posted on Tuesday, April 05, 2005 11:22 AM | Filed Under [ 闲话集锦 ] | 收藏本页 (百度搜藏)(QQ书签)(Live收藏)(Google书签)(Yahoo书签)(新浪ViVi)(搜狐网摘)(365Key网摘)(天极网摘)(博采网摘)(和讯网摘)