Domanda

Vorrei fare l'equivalente di:

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

A seguito di Biri s link, Ho preso questo pezzo (modificato per rimuovere metodo obsoleto 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;

}  
È stato utile?

Soluzione

Utilizzando compilare al volo, come questo esempio mostra.

O utilizzando Fuggire, che è esattamente per la stessa ragione.

Altri suggerimenti

Ho scritto un progetto open source, Dinamica Espresso, che può convertire espressione del testo scritto utilizzando una sintassi C# in delegati (o struttura ad albero dell'espressione).Testo le espressioni vengono analizzati e trasformati in Espressione Alberi senza l'utilizzo di compilazione o di riflessione.

È possibile scrivere qualcosa come:

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

o

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

Il mio lavoro è basato su Scott Gu articolo http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx .

Argomento vecchio, ma considerando che questo è uno dei primi thread che mostra quando googling, qui è una soluzione aggiornata.

È possibile utilizzare Roslyn nuove API di Scripting per valutare le espressioni.

Se si utilizza NuGet, basta aggiungere una dipendenza di Microsoft.CodeAnalysis.CSharp.Scripting.Per valutare gli esempi che hai fornito, è molto semplice:

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

Questo, ovviamente, non fa uso di script di un motore asincrono capacità.

È inoltre possibile specificare l'valutato il tipo di risultato come previsto:

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

Per valutare più avanzate, frammenti di codice, passaggio di parametri, di fornire i riferimenti, gli spazi dei nomi e quant'altro, controllare il wiki linkato sopra.

Se si desidera specificatamente chiamata in codice assembly e nel proprio progetto, vorrei avvocato che utilizza il C# CodeDom CodeProvider.

Ecco un elenco dei più popolari metodi che conosco per la valutazione di espressioni stringa in modo dinamico in C#.

Le Soluzioni Microsoft

Soluzioni Non Microsoft (non che ci sia nulla di male)

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

Quali sono le implicazioni in termini di prestazioni di fare questo?

Utilizziamo un sistema basato su qualcosa come il precedente, in cui ogni C# script viene compilato in memoria di montaggio ed eseguito in un AppDomain separato.Non c'è la cache di sistema di sicurezza, in modo che gli script sono ricompilato ogni volta che sono in esecuzione.Ho fatto alcuni test di base e molto semplice "Hello World" compilazione dello script in circa 0,7 secondi sulla mia macchina, incluso il caricamento degli script dal disco.0,7 secondi è bene per un sistema di scripting, ma potrebbe essere troppo lento per rispondere all'input dell'utente, in questo caso dedicato parser/compilatore come Fuggire potrebbe essere migliore.

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

Sembra che ci sia anche un modo di farlo usando l'espressione regolare e XPathNavigator per valutare l'espressione.Non ho avuto la possibilità di provarlo, ma mi è piaciuto, perché non richiedono di compilare il codice in fase di esecuzione o di utilizzare le librerie che potrebbero non essere disponibili.

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

Ci proverò e dire poi se ha funzionato.Ho anche intenzione di provare in Silverlight, ma è troppo tardi e mi sono quasi addormentato a farlo adesso.

Mentre C# non ha il supporto per un Eval metodo nativo, ho un C# eval programma che consente la valutazione di codice C#.Esso fornisce per la valutazione di codice C# in fase di runtime e supporta molti C# consolidato.In realtà, questo codice è utilizzabile all'interno di qualsiasi .Progetto in rete, tuttavia, è limitata all'utilizzo di C# sintassi.Dare un'occhiata al mio sito web, http://csharp-eval.com, per ulteriori dettagli.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top