如何动态评估 C# 表达式? [英] How can I evaluate a C# expression dynamically?
问题描述
我想做相当于:
object result = Eval("1 + 3");
string now = Eval("System.DateTime.Now().ToString()") as string
在 Biri s link 之后,我得到了这个片段(修改以删除过时的方法 ICodeCompiler.CreateCompiler()
:
Following Biri s link, I got this snippet (modified to remove obsolete method 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;
");
sb.Append("namespace CSCodeEvaler{
");
sb.Append("public class CSCodeEvaler{
");
sb.Append("public object EvalCode(){
");
sb.Append("return " + sExpression + ";
");
sb.Append("}
");
sb.Append("}
");
sb.Append("}
");
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;
}
推荐答案
老话题,但考虑到这是谷歌搜索时出现的第一个线程,这里有一个更新的解决方案.
Old topic, but considering this is one of the first threads showing up when googling, here is an updated solution.
您可以使用 Roslyn 的新脚本 API 来计算表达式.
如果您使用的是 NuGet,只需将依赖项添加到 Microsoft.CodeAnalysis.CSharp.Scripting.要评估您提供的示例,很简单:
If you are using NuGet, just add a dependency to Microsoft.CodeAnalysis.CSharp.Scripting. To evaluate the examples you provided, it is as simple as:
var result = CSharpScript.EvaluateAsync("1 + 3").Result;
这显然没有利用脚本引擎的异步功能.
This obviously does not make use of the scripting engine's async capabilities.
您还可以根据需要指定评估结果类型:
You can also specify the evaluated result type as you intended:
var now = CSharpScript.EvaluateAsync<string>("System.DateTime.Now.ToString()").Result;
要评估更高级的代码片段、传递参数、提供引用、命名空间等,请查看上面链接的 wiki.
To evaluate more advanced code snippets, pass parameters, provide references, namespaces and whatnot, check the wiki linked above.
这篇关于如何动态评估 C# 表达式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!