Wie kann ich einen C # -Ausdruck dynamisch auswerten?

Ich möchte das Äquivalent machen von:

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

Nach dem Biri- Link habe ich dieses Snippet (modifiziert, um die obsolete Methode ICodeCompiler.CreateCompiler() 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; } 

Solutions Collecting From Web of "Wie kann ich einen C # -Ausdruck dynamisch auswerten?"

Indem Sie das Kompilieren im laufenden Betrieb verwenden, wie in diesem Beispiel gezeigt.

Oder mit Flee , das genau aus dem gleichen Grund ist.

Ich habe ein Open-Source-Projekt, Dynamic Expresso , geschrieben, das Textausdrücke, die mit einer C # -Syntax geschrieben wurden, in Delegaten (oder Ausdrucksbaum) umwandeln kann. Textausdrücke werden analysiert und in Ausdrucksstrukturen umgewandelt, ohne dass eine Kompilierung oder Reflektion verwendet wird.

Sie können etwas schreiben wie:

 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-query-library.aspx .

Altes Thema, aber wenn man bedenkt, dass dies einer der ersten Threads ist, die beim googlen auftauchen, ist hier eine aktualisierte Lösung.

Sie können Roslyns neue Scripting-API zum Auswerten von Ausdrücken verwenden .

Wenn Sie NuGet verwenden, fügen Sie eine Abhängigkeit zu Microsoft.CodeAnalysis.CSharp.Scripting hinzu . Um die von Ihnen bereitgestellten Beispiele zu bewerten, ist es so einfach wie:

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

Dies nutzt offensichtlich nicht die Async-Fähigkeiten der Scripting Engine.

Sie können den bewerteten Ergebnistyp auch wie gewünscht angeben:

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

Um erweiterte Code-Snippets zu bewerten, Parameter zu übergeben, Referenzen, Namespaces und whatnot bereitzustellen, überprüfen Sie das oben verlinkte Wiki.

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

Während C # nativ keine Unterstützung für eine Eval-Methode bietet, habe ich ein C # -EVAL-Programm, mit dem C # -Code ausgewertet werden kann. Es ermöglicht die Auswertung von C # -Code zur Laufzeit und unterstützt viele C # -statementen. Tatsächlich ist dieser Code in jedem .NET-Projekt verwendbar, ist jedoch auf die Verwendung von C # -Syntax beschränkt. Weitere Informationen finden Sie auf meiner Website http://csharp-eval.com .

Welche Auswirkungen hat dies auf die performance?

Wir verwenden ein System, das auf etwas wie dem oben Erwähnten basiert, wobei jedes C # -Skript zu einer In-Memory-Assembly kompiliert und in einer separaten AppDomain ausgeführt wird. Es gibt noch kein Caching-System, daher werden die Skripte jedes Mal neu kompiliert, wenn sie ausgeführt werden. Ich habe ein paar einfache Tests durchgeführt und ein sehr einfaches “Hello World” -Skript kompiliert in etwa 0,7 Sekunden auf meinem Rechner, einschließlich des Ladens des Skripts von der Festplatte. 0,7 Sekunden sind für ein Skript-System in Ordnung, aber möglicherweise zu langsam, um auf Benutzereingaben zu reagieren. In diesem Fall könnte ein dedizierter Parser / Compiler wie Fliese besser sein.

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

Es scheint, dass es auch eine Möglichkeit gibt, RegEx und XPathNavigator zu verwenden, um den Ausdruck auszuwerten. Ich hatte noch keine Gelegenheit, es zu testen, aber ich mochte es irgendwie, weil es keinen Code zur Laufzeit kompilieren oder Bibliotheken verwenden musste, die nicht verfügbar sein konnten.

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 hat. Ich habe auch vor, es in Silverlight zu versuchen, aber es ist zu spät und ich bin fast eingeschlafen, um es jetzt zu tun.