How can I evaluate a C# expression dynamically?

后端 未结 7 1224
情话喂你
情话喂你 2020-11-22 07:22

I would like to do the equivalent of:

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

相关标签:
7条回答
  • 2020-11-22 08:03

    Old topic, but considering this is one of the first threads showing up when googling, here is an updated solution.

    You can use Roslyn's new Scripting API to evaluate expressions.

    If you are using NuGet, just add a dependency to Microsoft.CodeAnalysis.CSharp.Scripting. To evaluate the examples you provided, it is as simple as:

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

    This obviously does not make use of the scripting engine's async capabilities.

    You can also specify the evaluated result type as you intended:

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

    To evaluate more advanced code snippets, pass parameters, provide references, namespaces and whatnot, check the wiki linked above.

    0 讨论(0)
  • 2020-11-22 08:03

    I have written an open source project, Dynamic Expresso, that can convert text expression written using a C# syntax into delegates (or expression tree). Text expressions are parsed and transformed into Expression Trees without using compilation or reflection.

    You can write something like:

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

    or

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

    My work is based on Scott Gu article http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx .

    0 讨论(0)
  • 2020-11-22 08:11
    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;
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 08:15

    If you specifically want to call into code and assemblies in your own project I would advocate using the C# CodeDom CodeProvider.

    Here is a list of the most popular approaches that I am aware of for evaluating string expressions dynamically in C#.

    Microsoft Solutions

    • C# CodeDom CodeProvider:
      • See How LINQ used to work and this CodeProject article
    • Roslyn:
      • See this article on Rosly Emit API and this StackOverflow answer
    • DataTable.Compute:
      • See this answer on StackOverflow
    • Webbrowser.Document.InvokeScript
      • See this StackOverflow question
    • DataBinder.Eval
    • ScriptControl
      • See this answer on StackOverflow and this question
    • Executing PowerShell:
      • See this CodeProject article

    Non-Microsoft solutions (not that there is anything wrong with that)

    • Expression evaluation libraries:
      • Flee
      • DynamicExpresso
      • NCalc
      • CodingSeb.ExpressionEvaluator
      • Eval-Expression.NET
    • Javascript interpreter
      • Jint
    • To execute real C#
      • CS-Script
    • Roll your own a language building toolkit like:
      • Irony
      • Jigsaw
    0 讨论(0)
  • 2020-11-22 08:24

    What are the performance implications of doing this?

    We use a system based on something like the above mentioned, where each C# script is compiled to an in-memory assembly and executed in a separate AppDomain. There's no caching system yet, so the scripts are recompiled every time they run. I've done some simple testing and a very simple "Hello World" script compiles in about 0.7 seconds on my machine, including loading the script from disk. 0.7 seconds is fine for a scripting system, but might be too slow for responding to user input, in that case a dedicated parser/compiler like Flee might be better.

    using System;
    public class Test
    {
        static public void DoStuff( Scripting.IJob Job)
        {
            Console.WriteLine( "Heps" );
        }
    }
    
    0 讨论(0)
  • 2020-11-22 08:24

    Looks like there is also a way of doing it using RegEx and XPathNavigator to evaluate the expression. I did not have the chance to test it yet but I kind of liked it because it did not require to compile code at runtime or use libraries that could not be available.

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

    I'll try it and tell later if it worked. I also intend to try it in Silverlight, but it is too late and I'm almost asleep to do it now.

    0 讨论(0)
提交回复
热议问题