我想做相当于:
object result = Eval("1 + 3"); string now = Eval("System.DateTime.Now().ToString()") as string
在Biri的链接之后,我得到了这个片段(修改后删除了过时的方法ICodeCompiler.CreateCompiler()
:
private object Eval(string sExpression) { CSharpCodeProvider c = new CSharpCodeProvider(); CompilerParameters cp = new CompilerParameters(); cp.ReferencedAssemblies.Add("system.dll"); cp.CompilerOptions = "/t:library"; cp.GenerateInMemory = true; StringBuilder sb = new StringBuilder(""); sb.Append("using System;\n"); sb.Append("namespace CSCodeEvaler{ \n"); sb.Append("public class CSCodeEvaler{ \n"); sb.Append("public object EvalCode(){\n"); sb.Append("return " + sExpression + "; \n"); sb.Append("} \n"); sb.Append("} \n"); sb.Append("}\n"); CompilerResults cr = c.CompileAssemblyFromSource(cp, sb.ToString()); if (cr.Errors.Count > 0) { throw new InvalidExpressionException( string.Format("Error ({0}) evaluating: {1}", cr.Errors[0].ErrorText, sExpression)); } System.Reflection.Assembly a = cr.CompiledAssembly; object o = a.CreateInstance("CSCodeEvaler.CSCodeEvaler"); Type t = o.GetType(); MethodInfo mi = t.GetMethod("EvalCode"); object s = mi.Invoke(o, null); return s; }
小智.. 26
老话题,但考虑到这是谷歌搜索时出现的第一个线程之一,这是一个更新的解决方案.
您可以使用Roslyn的新Scripting API来计算表达式.
如果您正在使用NuGet,只需向Microsoft.CodeAnalysis.CSharp.Scripting添加依赖项.要评估您提供的示例,它很简单:
var result = CSharpScript.EvaluateAsync("1 + 3").Result;
这显然没有利用脚本引擎的异步功能.
您还可以按预期指定评估结果类型:
var now = CSharpScript.EvaluateAsync("System.DateTime.Now.ToString()").Result;
要评估更高级的代码片段,传递参数,提供引用,命名空间等等,请检查上面链接的wiki.
老话题,但考虑到这是谷歌搜索时出现的第一个线程之一,这是一个更新的解决方案.
您可以使用Roslyn的新Scripting API来计算表达式.
如果您正在使用NuGet,只需向Microsoft.CodeAnalysis.CSharp.Scripting添加依赖项.要评估您提供的示例,它很简单:
var result = CSharpScript.EvaluateAsync("1 + 3").Result;
这显然没有利用脚本引擎的异步功能.
您还可以按预期指定评估结果类型:
var now = CSharpScript.EvaluateAsync("System.DateTime.Now.ToString()").Result;
要评估更高级的代码片段,传递参数,提供引用,命名空间等等,请检查上面链接的wiki.
我编写了一个开源项目Dynamic Expresso,它可以将使用C#语法编写的文本表达式转换为委托(或表达式树).解析文本表达式并将其转换为表达式树,而无需使用编译或反射.
你可以这样写:
var interpreter = new Interpreter(); var result = interpreter.Eval("8 / 2 + 2");
要么
var interpreter = new Interpreter() .SetVariable("service", new ServiceExample()); string expression = "x > 4 ? service.aMethod() : service.AnotherMethod()"; Lambda parsedExpression = interpreter.Parse(expression, new Parameter("x", typeof(int))); parsedExpression.Invoke(5);
我的工作基于Scott Gu的文章http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx.
如果您特别想在自己的项目中调用代码和程序集,则建议使用C#CodeDom CodeProvider。
这是我所知道的用于在C#中动态评估字符串表达式的最流行方法的列表。
C#CodeDom CodeProvider:
请参阅LINQ过去的工作方式和此CodeProject文章
罗斯林:
参阅有关Rosly Emit API的文章和此StackOverflow答案
DataTable.Compute:
在StackOverflow上查看此答案
Webbrowser.Document.InvokeScript
看到这个StackOverflow问题
数据绑定器
脚本控制
请参阅StackOverflow上的此答案以及此问题
执行PowerShell:
请参阅此CodeProject文章
表达评估库:
逃跑
动态表情
计算器
推出自己的语言构建工具包,例如:
讽刺
拼图