Comment puis-je évaluer une expression C # de manière dynamic?

Je voudrais faire l’équivalent de:

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

Après le lien de Biri, j’ai eu cet extrait (modifié pour supprimer la méthode obsolète ICodeComstackr.CreateComstackr() :

 private object Eval(ssortingng sExpression) { CSharpCodeProvider c = new CSharpCodeProvider(); ComstackrParameters cp = new ComstackrParameters(); cp.ReferencedAssemblies.Add("system.dll"); cp.ComstackrOptions = "/t:library"; cp.GenerateInMemory = true; SsortingngBuilder sb = new SsortingngBuilder(""); 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"); ComstackrResults cr = c.ComstackAssemblyFromSource(cp, sb.ToSsortingng()); if (cr.Errors.Count > 0) { throw new InvalidExpressionException( ssortingng.Format("Error ({0}) evaluating: {1}", cr.Errors[0].ErrorText, sExpression)); } System.Reflection.Assembly a = cr.ComstackdAssembly; object o = a.CreateInstance("CSCodeEvaler.CSCodeEvaler"); Type t = o.GetType(); MethodInfo mi = t.GetMethod("EvalCode"); object s = mi.Invoke(o, null); return s; } 

En utilisant la compilation à la volée, comme le montre cet exemple .

Ou en utilisant Flee , pour la même raison.

J’ai écrit un projet open source, Dynamic Expresso , qui peut convertir une expression de texte écrite à l’aide d’une syntaxe C # en delegates (ou arbre d’expression). Les expressions de texte sont analysées et transformées en arbres d’expression sans utiliser de compilation ni de reflection.

Vous pouvez écrire quelque chose comme:

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

ou

 var interpreter = new Interpreter() .SetVariable("service", new ServiceExample()); ssortingng expression = "x > 4 ? service.aMethod() : service.AnotherMethod()"; Lambda parsedExpression = interpreter.Parse(expression, new Parameter("x", typeof(int))); parsedExpression.Invoke(5); 

Mon travail est basé sur l’article de Scott Gu http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx .

Ancien sujet, mais étant donné que c’est l’un des premiers fils apparaissant sur Google, voici une solution mise à jour.

Vous pouvez utiliser la nouvelle API de script de Roslyn pour évaluer les expressions .

Si vous utilisez NuGet, ajoutez simplement une dépendance à Microsoft.CodeAnalysis.CSharp.Scripting . Pour évaluer les exemples que vous avez fournis, c’est aussi simple que:

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

Cela n’utilise évidemment pas les capacités asynchrones du moteur de script.

Vous pouvez également spécifier le type de résultat évalué tel que prévu:

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

Pour évaluer des fragments de code plus avancés, des parameters de transmission, des références, des espaces de noms et autres, consultez le wiki lié ci-dessus.

 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 Ssortingng Evaluate(ssortingng expr) { var engine = (INeedEngine)this; var result = Eval.JScriptEvaluate(expr, engine.GetEngine()); return Convert.ToSsortingng(result, true); } VsaEngine INeedEngine.GetEngine() { vsaEngine = vsaEngine ?? VsaEngine.CreateEngineWithType(this.GetType().TypeHandle); return vsaEngine; } void INeedEngine.SetEngine(VsaEngine engine) { vsaEngine = engine; } } } 

Bien que C # ne prenne pas en charge de manière native une méthode Eval, j’ai un programme C # eval qui permet d’évaluer le code C #. Il permet d’évaluer le code C # à l’exécution et prend en charge de nombreuses instructions C #. En fait, ce code est utilisable dans tout projet .NET, mais il est limité à la syntaxe C #. Consultez mon site Web, http://csharp-eval.com , pour plus de détails.

Quelles sont les implications de performance de faire cela?

Nous utilisons un système basé sur quelque chose comme ce qui est mentionné ci-dessus, où chaque script C # est compilé dans un assemblage en mémoire et exécuté dans un AppDomain distinct. Il n’y a pas encore de système de cache, donc les scripts sont recompilés à chaque exécution. J’ai fait quelques tests simples et un script très simple “Hello World” comstack en 0,7 seconde environ sur ma machine, y compris le chargement du script depuis le disque. 0,7 seconde est bon pour un système de script, mais peut être trop lent pour répondre à une entrée utilisateur, dans ce cas un parsingur / compilateur dédié comme Flee pourrait être mieux.

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

On dirait qu’il y a aussi un moyen de le faire en utilisant RegEx et XPathNavigator pour évaluer l’expression. Je n’ai pas encore eu l’occasion de le tester, mais je l’ai en quelque sorte aimé car il ne nécessitait pas de comstackr du code à l’exécution ou d’utiliser des bibliothèques qui n’étaient pas disponibles.

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

Je vais l’essayer et dire plus tard si cela a fonctionné. J’ai aussi l’intention de l’essayer dans Silverlight, mais il est trop tard et je suis presque endormi pour le faire maintenant.