How can I evaluate C# code dynamically?

后端 未结 16 1956
[愿得一人]
[愿得一人] 2020-11-22 03:37

I can do an eval(\"something()\"); to execute the code dynamically in JavaScript. Is there a way for me to do the same thing in C#?

An example of what I

相关标签:
16条回答
  • 2020-11-22 04:22

    Uses reflection to parse and evaluate a data-binding expression against an object at run time.

    DataBinder.Eval Method

    0 讨论(0)
  • 2020-11-22 04:24

    Using the Roslyn scripting API (more samples here):

    // add NuGet package 'Microsoft.CodeAnalysis.Scripting'
    using Microsoft.CodeAnalysis.CSharp.Scripting;
    
    await CSharpScript.EvaluateAsync("System.Math.Pow(2, 4)") // returns 16
    

    You can also run any piece of code:

    var script = await CSharpScript.RunAsync(@"
                    class MyClass
                    { 
                        public void Print() => System.Console.WriteLine(1);
                    }")
    

    And reference the code that was generated in previous runs:

    await script.ContinueWithAsync("new MyClass().Print();");
    
    0 讨论(0)
  • 2020-11-22 04:25

    I was trying to get a value of a structure (class) member by it's name. The structure was not dynamic. All answers didn't work until I finally got it:

    public static object GetPropertyValue(object instance, string memberName)
    {
        return instance.GetType().GetField(memberName).GetValue(instance);
    }
    

    This method will return the value of the member by it's name. It works on regular structure (class).

    0 讨论(0)
  • 2020-11-22 04:29

    This is an eval function under c#. I used it to convert anonymous functions (Lambda Expressions) from a string. Source: http://www.codeproject.com/KB/cs/evalcscode.aspx

    public static object Eval(string sCSCode) {
    
      CSharpCodeProvider c = new CSharpCodeProvider();
      ICodeCompiler icc = c.CreateCompiler();
      CompilerParameters cp = new CompilerParameters();
    
      cp.ReferencedAssemblies.Add("system.dll");
      cp.ReferencedAssemblies.Add("system.xml.dll");
      cp.ReferencedAssemblies.Add("system.data.dll");
      cp.ReferencedAssemblies.Add("system.windows.forms.dll");
      cp.ReferencedAssemblies.Add("system.drawing.dll");
    
      cp.CompilerOptions = "/t:library";
      cp.GenerateInMemory = true;
    
      StringBuilder sb = new StringBuilder("");
      sb.Append("using System;\n" );
      sb.Append("using System.Xml;\n");
      sb.Append("using System.Data;\n");
      sb.Append("using System.Data.SqlClient;\n");
      sb.Append("using System.Windows.Forms;\n");
      sb.Append("using System.Drawing;\n");
    
      sb.Append("namespace CSCodeEvaler{ \n");
      sb.Append("public class CSCodeEvaler{ \n");
      sb.Append("public object EvalCode(){\n");
      sb.Append("return "+sCSCode+"; \n");
      sb.Append("} \n");
      sb.Append("} \n");
      sb.Append("}\n");
    
      CompilerResults cr = icc.CompileAssemblyFromSource(cp, sb.ToString());
      if( cr.Errors.Count > 0 ){
          MessageBox.Show("ERROR: " + cr.Errors[0].ErrorText, 
             "Error evaluating cs code", MessageBoxButtons.OK, 
             MessageBoxIcon.Error );
          return null;
      }
    
      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;
    
    }
    
    0 讨论(0)
提交回复
热议问题