【问题标题】:Compile the code in the form of a string以字符串的形式编译代码
【发布时间】:2014-02-04 14:05:00
【问题描述】:

场景:

我有我的函数名称和存储在数据库中的参数。函数名和参数从数据库返回为

"FunctionName(Convert.ToString("harry"),Convert.ToString("Password"),Convert.ToInt32("5"),Convert.ToString(""),Convert.ToString("AMER_02772"),Convert.ToInt32("0"))"

问题:

现在我想执行这个作为字符串返回给我的函数?请指导我执行此字符串的方法?

我读过类似的帖子,但找不到确切的结果。

【问题讨论】:

  • 看看反射
  • 这实际上相当复杂。它本质上将涉及创建一个动态程序集;例如,字符串中的代码必须在运行时编译。需要 System.CodeDom 命名空间。看看这个 SO 问题:stackoverflow.com/questions/4800267/…

标签: c# asp.net compiler-construction


【解决方案1】:

你可以使用GetMethod,这是示例代码

using System;
using System.Reflection;

static class Methods
 {
public static void Inform(string parameter)
{
Console.WriteLine("Inform:parameter={0}", parameter);
}
 }

class Program
{
    static void Main()
    {
    // Name of the method we want to call.
    string name = "Inform";

    // Call it with each of these parameters.
    string[] parameters = { "Sam", "Perls" };

    // Get MethodInfo.
    Type type = typeof(Methods);
    MethodInfo info = type.GetMethod(name);

    // Loop over parameters.
    foreach (string parameter in parameters)
    {
        info.Invoke(null, new object[] { parameter });
    }
    }
}

Output

Inform:parameter=Sam
Inform:parameter=Perls

或者

您可以参考Dynamically invoking any function by passing function name as string
还有CodeProject 链接Dynamically Invoke A Method, Given Strings with Method Name and Class Name

【讨论】:

    【解决方案2】:

    看看CSharpCodeProvider class

    举个例子:

    var csc = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v3.5" } });
            var parameters = new CompilerParameters(new[] { "mscorlib.dll", "System.Core.dll" });
            parameters.GenerateExecutable = false;
            CompilerResults results = csc.CompileAssemblyFromSource(parameters,
            @"using System.Linq;
                class MyClass {
                  public void MyFunction() {
                    var q = from i in Enumerable.Range(1,100)
                              where i % 2 == 0
                              select i;
                  }
                }");
            results.Errors.Cast<CompilerError>().ToList().ForEach(error => Console.WriteLine(error.ErrorText));
    

    【讨论】:

      【解决方案3】:

      您可以使用CodeDomProvider 编译C# 代码。然后使用反射获取类型信息,创建对象并调用它的方法。

      有关示例,请参阅 this answer

      基本上是这样工作的:

          string source = ...
          string references = ...
      
          // Compile
          CodeDomProvider provider = new CSharpCodeProvider();
          CompilerParameters cp = new CompilerParameters(references);
          cp.GenerateExecutable = false;
          cp.GenerateInMemory = true;
          CompilerResults res = provider.CompileAssemblyFromSource(cp, source);
      
          // Extract object
          Type t = res.CompiledAssembly.GetType(className);
          MethodInfo method = t.GetMethod(methodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);          // Get method
      
          // Run
          object instance =  Activator.CreateInstance(t, this);
          object ret = method.Invoke(instance, null); 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-08-09
        • 2019-06-13
        • 1970-01-01
        • 1970-01-01
        • 2013-07-31
        • 2015-07-24
        • 1970-01-01
        相关资源
        最近更新 更多