string now = Eval"System.DateTime.Now().ToString()" as string在Biri的链接之后,我得到了以下代"/>

关于反射:如何动态评估C#表达式?

关于反射:如何动态评估C#表达式?

How can I evaluate a C# expression dynamically?

我想做相当于:

1
2
object result = Eval("1 + 3");
string now    = Eval("System.DateTime.Now().ToString()") as string

在Biri的链接之后,我得到了以下代码片段(已修改为删除过时的方法ICodeCompiler.CreateCompiler()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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;

}

旧话题,但是考虑到这是在谷歌搜索时显示的第一个线程,这是一个更新的解决方案。

您可以使用Roslyn的新脚本API评估表达式。

如果您使用的是NuGet,则只需向Microsoft.CodeAnalysis.CSharp.Scripting添加一个依赖项。
要评估您提供的示例,它很简单:

1
var result = CSharpScript.EvaluateAsync("1 + 3").Result;

显然,这没有利用脚本引擎的异步功能。

您还可以根据需要指定评估结果类型:

1
var now = CSharpScript.EvaluateAsync<string>("System.DateTime.Now.ToString()").Result;

要评估更多高级代码段,传递参数,提供引用,名称空间和其他内容,请查看上面链接的Wiki。


我已经编写了一个开源项目Dynamic Expresso,该项目可以将使用C#语法编写的文本表达式转换为委托(或表达式树)。无需使用编译或反射即可将文本表达式解析并转换为表达式树。

您可以这样写:

1
2
var interpreter = new Interpreter();
var result = interpreter.Eval("8 / 2 + 2");

要么

1
2
3
4
5
6
7
8
9
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文章

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

  • 表达评估库:

    • 逃跑
    • 动态表情
    • 计算器
    • CodingSeb.ExpressionEvaluator
    • 评估表达网
  • JavaScript解释器

    • 金特
  • 执行真实的C#

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

    • 讽刺
    • 拼图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using System;
using Microsoft.JScript;
using Microsoft.JScript.Vsa;
using Convert = Microsoft.JScript.Convert;

namespace System
{
    public class MathEvaluator : INeedEngine
    {
        private VsaEngine vsaEngine;

        public virtual String Evaluate(string expr)
        {
            var engine = (INeedEngine)this;
            var result = Eval.JScriptEvaluate(expr, engine.GetEngine());

            return Convert.ToString(result, true);
        }

        VsaEngine INeedEngine.GetEngine()
        {
            vsaEngine = vsaEngine ?? VsaEngine.CreateEngineWithType(this.GetType().TypeHandle);
            return vsaEngine;
        }

        void INeedEngine.SetEngine(VsaEngine engine)
        {
            vsaEngine = engine;
        }
    }
}

What are the performance implications of doing this?

我们使用基于上述内容的系统,其中每个C#脚本都编译为内存中的程序集,并在单独的AppDomain中执行。还没有缓存系统,因此脚本每次运行时都会重新编译。我已经进行了一些简单的测试,并且非常简单的" Hello World"脚本在我的计算机上编译了大约0.7秒,包括从磁盘加载脚本。 0.7秒对于脚本系统来说可以,但是对于响应用户输入可能太慢,在这种情况下,像Flee这样的专用解析器/编译器可能更好。

1
2
3
4
5
6
7
8
using System;
public class Test
{
    static public void DoStuff( Scripting.IJob Job)
    {
        Console.WriteLine("Heps" );
    }
}

虽然C#本机不支持Eval方法,但我有一个C#eval程序,它允许评估C#代码。它提供了在运行时评估C#代码的功能,并支持许多C#语句。实际上,此代码可在任何.NET项目中使用,但是仅限于使用C#语法。请查看我的网站http://csharp-eval.com,以获取更多详细信息。


看起来还有一种使用RegEx和XPathNavigator评估表达式的方法。我还没有机会对其进行测试,但是我有点喜欢它,因为它不需要在运行时编译代码或使用无法使用的库。

http://www.webtips.co.in/c/evaluate-function-in-c-net-as-eval-function-in-javascript.aspx

我会尝试一下,然后告诉它是否有效。我也打算在Silverlight中尝试它,但是为时已晚,现在我几乎睡着了。


推荐阅读

    linux重新链接库命令?

    linux重新链接库命令?,代码,软件,平台,产品,电脑,系统,入口,市场,工业,通信,l

    linux链接远程命令?

    linux链接远程命令?,系统,地址,网络,密码,软件,名称,工具,服务,电脑,认证,如

    linux查看动态命令?

    linux查看动态命令?,系统,状态,工具,实时,时间,命令,工作,信息,地址,百分比,l

    linux命令行链接网络?

    linux命令行链接网络?,网络,系统,地址,工作,工具,最新,网址,数据,信息,环境,l

    linux动态链接库命令?

    linux动态链接库命令?,代码,项目,工程,电脑,网上,文件,程序,静态,命令,目录,

    linux动态执行命令?

    linux动态执行命令?,时间,信息,名字,工作,网上,业务,工具,对比,地址,下来,如

    linux取消链接命令行?

    linux取消链接命令行?,工具,状态,环境,数据,命令,文件,终端,模式,指令,界面,l

    linux删除硬链接命令?

    linux删除硬链接命令?,工作,数据,系统,信息,链接,命令,设备,名称,不了,概念,l

    linux创建软链接命令?

    linux创建软链接命令?,工作,地址,位置,系统,信息,管理,服务,名字,链接,文件,

    linux命令行动态输出?

    linux命令行动态输出?,标准,工作,信息,系统,命令,地址,文件,数据,管理,设备,l

    linux命令正则表达式?

    linux命令正则表达式?,工作,环境,基础,网络,单位,名称,平台,信息,正规,管理,L

    linux中软链接命令?

    linux中软链接命令?,位置,设备,数据,信息,系统,文件,链接,地址,对比,源文件,L

    linux命令链接网页?

    linux命令链接网页?,网络,信息,系统,网址,工具,网站,状态,发行,数据,命令,Lin

    linux软链接命令用法?

    linux软链接命令用法?,时间,系统,位置,服务,链接,数据,地址,基础,不了,信息,L

    linux目录链接命令?

    linux目录链接命令?,系统,工作,时间,地址,数据,信息,管理,目录,文件,命令,请

    linux命令创建硬链接?

    linux命令创建硬链接?,数据,链接,系统,文件,位置,概念,不了,源文件,目录,命

    linux复制链接命令?

    linux复制链接命令?,系统,认证,文件,命令,目录,源文件,选项,目标,功能,语法,L

    linux文字动态命令?

    linux文字动态命令?,系统,工作,地址,工具,管理,网络,命令,分析,目录,代码,Lin

    linux下软链接命令?

    linux下软链接命令?,位置,地址,信息,工作,设备,系统,文件,链接,命令,源文件,

    linux链接网络命令?

    linux链接网络命令?,系统,网络,工作,信息,设备,管理,名字,地址,命令,标准,Lin