Question

Je voudrais faire l'équivalent de:

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

Suivant Biri s lien, J'ai reçu cette extrait de (modifié pour supprimer obsolètes méthode 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;

}  
Était-ce utile?

La solution

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

Ou en utilisant Fuir, qui est exactement pour la même raison.

Autres conseils

J'ai écrit un projet open source, Dynamique Expresso, que peut convertir le texte en expression écrite à l'aide d'une syntaxe C# dans délégués (ou de l'expression de l'arbre).Expressions de texte sont analysées et transformées en Des Arbres D'Expression sans l'aide de la compilation ou de réflexion.

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

string 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 Scott Gu article http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx .

Vieux sujet, mais considérant que c'est l'un des premiers filets en place lors de googler, voici une mise à jour de la solution.

Vous pouvez utiliser Roslyn la nouvelle API de Script pour évaluer des expressions.

Si vous êtes à l'aide de NuGet, il suffit d'ajouter une dépendance à Microsoft.CodeAnalysis.CSharp.Script.Pour évaluer les exemples que vous avez fourni, c'est aussi simple que:

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

Ce n'est évidemment pas faire usage du moteur de script asynchrone capacités.

Vous pouvez également spécifier le résultat évaluée type comme vous le souhaitez:

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

Pour évaluer plus avancé des extraits de code, de passer des paramètres, fournir des références, des espaces de noms et autres joyeusetés, consultez le wiki ci-dessus.

Si vous souhaitez appeler dans le code et assemblées dans votre propre projet, je voudrais plaider à l'aide de la C# CodeDom CodeProvider.

Voici une liste des approches les plus populaires que je suis au courant pour l'évaluation des expressions de chaîne de façon dynamique en C#.

Les Solutions Microsoft

Solutions Non-Microsoft (il n'y a rien de mal à cela)

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

Quelles sont les implications sur les performances de faire cela?

Nous utilisons un système basé sur quelque chose comme mentionné ci-dessus, où chaque C# script est compilé en un-mémoire de l'assemblée et exécutée dans un autre domaine d'application.Il n'y a pas de système de mise en cache, de sorte que les scripts sont recompilé à chaque fois qu'ils exécutent.J'ai fait quelques tests simples et très simple "Hello World" script compile dans environ 0,7 secondes sur ma machine, y compris le chargement, le script à partir du disque.0.7 secondes est très bien pour un système de script, mais peut-être trop lent pour répondre à la saisie de l'utilisateur, dans ce cas, un dédié analyseur/compilateur comme Fuir peut-être mieux.

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

Regarde comme il est également un moyen de le faire en utilisant les RegEx et XPathNavigator pour évaluer l'expression.Je n'ai pas eu la chance de le tester encore, mais j'ai un peu aimé parce qu'il n'a pas besoin de compiler du code au moment de l'exécution ou de l'utilisation des bibliothèques qui pourraient ne pas être disponibles.

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

Je vais l'essayer et de dire par la suite si cela a fonctionné.J'ai également l'intention de l'essayer dans Silverlight, mais il est trop tard et je suis presque endormi de le faire maintenant.

Tandis que le C# n'ont pas de support pour une méthode Eval en natif, j'ai un C# eval programme qui permet pour l'évaluation de code C#.Il prévoit l'évaluation de code C# au moment de l'exécution et prend en charge de nombreux C# consolidés.En fait, ce code n'est utilisable qu'à l'intérieur de tout .Un projet de réseau, cependant, elle est limitée à l'aide de la syntaxe C#.Jetez un oeil à mon site web, http://csharp-eval.com, pour plus de détails.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top