60

私は同等のことをしたい:

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;

}  
4

9 に答える 9

31

C# 構文を使用して記述されたテキスト式をデリゲート (または式ツリー) に変換できるオープン ソース プロジェクトDynamic Expressoを作成しました。テキスト式は、コンパイルやリフレクションを使用せずに解析され、式ツリーに変換されます。

次のように書くことができます:

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に基づいています。

于 2013-02-07T21:46:30.660 に答える
2
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;
        }
    }
}
于 2010-10-29T08:27:45.400 に答える
1

これを行うことのパフォーマンスへの影響は何ですか?

各 C# スクリプトがインメモリ アセンブリにコンパイルされ、個別の AppDomain で実行される、上記のようなものに基づくシステムを使用します。キャッシュ システムはまだないため、スクリプトは実行するたびに再コンパイルされます。簡単なテストをいくつか行ったところ、ディスクからのスクリプトのロードを含め、非常に単純な「Hello World」スクリプトが私のマシンで約 0.7 秒でコンパイルされました。スクリプト システムでは 0.7 秒で問題ありませんが、ユーザー入力に応答するには遅すぎる可能性があります。

using System;
public class Test
{
    static public void DoStuff( Scripting.IJob Job)
    {
        Console.WriteLine( "Heps" );
    }
}
于 2008-09-10T15:12:42.170 に答える
0

RegEx と XPathNavigator を使用して式を評価する方法もあるようです。まだテストする機会はありませんでしたが、実行時にコードをコンパイルしたり、利用できないライブラリを使用したりする必要がないため、気に入りました。

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

試してみて、うまくいったかどうかは後で説明します。私も Silverlight で試してみるつもりですが、手遅れで、ほとんど寝てしまいました。

于 2008-11-13T03:34:49.180 に答える