当前位置:  开发笔记 > 编程语言 > 正文

如何动态评估C#表达式?

如何解决《如何动态评估C#表达式?》经验,为你挑选了3个好方法。

我想做相当于:

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.



1> 小智..:

老话题,但考虑到这是谷歌搜索时出现的第一个线程之一,这是一个更新的解决方案.

您可以使用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.



2> Davide Icard..:

我编写了一个开源项目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.



3> cdiggins..:

如果您特别想在自己的项目中调用代码和程序集,则建议使用C#CodeDom CodeProvider。

这是我所知道的用于在C#中动态评估字符串表达式的最流行方法的列表。

微软解决方案

C#CodeDom CodeProvider:

请参阅LINQ过去的工作方式和此CodeProject文章

罗斯林:

参阅有关Rosly Emit API的文章和此StackOverflow答案

DataTable.Compute:

在StackOverflow上查看此答案

Webbrowser.Document.InvokeScript

看到这个StackOverflow问题

数据绑定器

脚本控制

请参阅StackOverflow上的此答案以及此问题

执行PowerShell:

请参阅此CodeProject文章

非Microsoft解决方案(不是说这有什么问题)

表达评估库:

逃跑

动态表情

计算器

推出自己的语言构建工具包,例如:

讽刺

拼图

推荐阅读
TXCWB_523
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有