Frage

Ich würde gerne das Äquivalent von Folgendem tun:

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

Im Anschluss an Biri s Verknüpfung, ich habe dieses Snippet erhalten (geändert, um veraltete Methode zu entfernen 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;

}  
War es hilfreich?

Lösung

Mit der on the fly mit kompilieren, wie diesem Beispiel zeigt.

oder mit Flee, die für genau den gleichen Grund.

Andere Tipps

Ich habe ein Open-Source-Projekt geschrieben, Dynamische Expresso , dass Textausdruck umwandeln kann mit einem schriftlichen C # Syntax in Teilnehmer (oder Ausdrucksbaum). Text Ausdrücke werden analysiert und umgewandelt in Expression Trees ohne Kompilierung oder Reflexion verwendet wird.

Sie können so etwas wie schreiben:

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

oder

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);

Meine Arbeit basiert auf Scott Gu Artikel http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic- abfrage library.aspx .

Altes Thema, aber dies unter Berücksichtigung einer der ersten Fäden zeigen, wenn googeln, hier ist eine aktualisierte Lösung.

Sie können mit Roslyn der neuen Scripting-API-Ausdrücke auszuwerten .

Wenn Sie NuGet verwenden, fügen Sie nur eine Abhängigkeit Microsoft.CodeAnalysis. CSharp.Scripting . Zur Auswertung der Beispiele, die Sie zur Verfügung gestellt, ist es so einfach wie:

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

Dies ist offensichtlich nicht Nutzung des Scripting-Engine Asynchron-Fähigkeiten machen.

Sie können auch die ausgewertete Ergebnis Typ angeben, wie Sie bestimmt:

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

Um erweiterte Code-Schnipsel zu bewerten, Parameter übergeben, liefern Hinweise, Namensräume und so weiter, überprüfen Sie die Wiki oben verknüpft.

Wenn Sie speziell nennen in Code und Baugruppen in Ihrem eigenen Projekt möchte ich befürworten die C # CodeDom CodeProvider .

Hier

ist eine Liste der beliebtesten Ansätze, die ich bin mir bewusst, für die Auswertung String-Ausdrücke dynamisch in C #.

Microsoft Solutions

Non-Microsoft-Lösungen (nicht, dass es etwas falsch mit, dass)

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;
        }
    }
}
  

Was sind die Auswirkungen auf die Leistung, dies zu tun?

Wir verwenden ein System, das auf so etwas wie die oben genannten, wobei jeder C # Skript zu einer In-Memory-Anordnung zusammengestellt und in einer separaten AppDomain ausgeführt. Es gibt keine Caching-System noch, so werden die Skripte jedesmal, wenn sie neu kompiliert laufen. Ich habe ein paar einfachen Tests und ein sehr einfaches „Hallo Welt“ Skript erstellt auf meinem Rechner in etwa 0,7 Sekunden erledigt, darunter das Skript von der Festplatte geladen werden. 0,7 Sekunden sind in Ordnung für ein Scripting-System, aber möglicherweise zu langsam für auf Benutzereingaben reagiert, in diesem Fall einen eigenen Parser / Compiler wie besser sein Fliehen könnte.

using System;
public class Test
{
    static public void DoStuff( Scripting.IJob Job)
    {
        Console.WriteLine( "Heps" );
    }
}

Sieht aus wie es ist auch ein Weg, es zu tun mit RegEx und XPathNavigator den Ausdruck auszuwerten. Ich habe nicht die Chance haben, es noch zu testen, aber ich irgendwie mochte es, weil es keinen Code zur Laufzeit oder Verwendung Bibliotheken kompilieren bedurften, die nicht verfügbar sein könnte.

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

Ich werde es versuchen und später sagen, ob es funktioniert. Ich beabsichtige, es auch in Silverlight zu versuchen, aber es ist zu spät und ich bin fast schlafend, es jetzt zu tun.

Während C # hat keine Unterstützung für eine Eval-Methode nativ, ich habe ein C # eval-Programm, das für die Bewertung C # -Code nicht gestattet. Es bietet für C # -Code zur Laufzeit zu bewerten und viele C # Anweisungen unterstützt. In der Tat ist dieser Code verwendbar innerhalb eines beliebigen .NET-Projektes, ist es jedoch zur Verwendung von C # Syntax begrenzt ist. Werfen Sie einen Blick auf meine Website, http://csharp-eval.com , für weitere Details.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top