主要是使用 CSharpCodeProvider,动态调用来进行返回。
首先会拼接成一个类的一个方法,然后返回这个方法的值。不过,因为还是使用反射,所以效率不高。
public static class StringHelper
{
private static string prefix = @"using System; public static class DynamicClass
{
public static double Bomb()
{";
public static string postfix = @"}}"; public static double Eval(this string strResult)
{
if (strResult == "" || strResult == null)
{
return ;
}
string strCode = prefix + "return " + strResult + ";" + postfix;
CompilerResults result = null;
using (CSharpCodeProvider provider = new CSharpCodeProvider())
{
var options = new CompilerParameters();
options.GenerateInMemory = true;
result = provider.CompileAssemblyFromSource(options, strCode);
if (result.Errors.HasErrors)
{
var errorMsg = new StringBuilder();
foreach (CompilerError error in result.Errors)
{
errorMsg.AppendFormat("Line:{0},Column:{1},Content:{2}", error.Line, error.Column, error.ErrorText);
}
Console.WriteLine(errorMsg.ToString());
}
else
{
Type dynamicClass = result.CompiledAssembly.GetType("DynamicClass");
object obj = dynamicClass.InvokeMember("Bomb", BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Public, null, null, null);
return (double)obj;
}
}
return ;
}
}
调用方法很简单:Console.WriteLine("1 + 2 + 3".Eval());
或者直接调用 JavaScript 的 Eval
public static object Eval(string s)
{
Microsoft.JScript.Vsa.VsaEngine ve = Microsoft.JScript.Vsa.VsaEngine.CreateEngine();
return Microsoft.JScript.Eval.JScriptEvaluate(s, ve);
}
还可以使用 DataTable 的 Compute进行计算
static DataTable dt = new DataTable();
public static object EvalDataTable(string s)
{
return dt.Compute(s, null);
}
相比较而言,DataTable 更快,其次 JavaScript的方法,最后就是反射的那个方法。