【问题标题】:how to get the value of a variable of dynamically compiled C# code如何获取动态编译的 C# 代码的变量的值
【发布时间】:2014-10-27 05:33:29
【问题描述】:

我在运行时构建一段代码并在运行时编译它。现在我需要在运行时获取动态代码中变量的结果。这是我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CSharp;
using System.CodeDom.Compiler;

class Program
{
    static void Main(string[] args)
    {
        var csc = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v3.5" } });
        var parameters = new CompilerParameters(new[] { "mscorlib.dll", "System.Core.dll" }, "Example.exe", true);
        parameters.GenerateExecutable = true;
        CompilerResults results = csc.CompileAssemblyFromSource(parameters,
        @"using System.Linq;
            class Program {
              public static void Main(string[] args) {
                int abc=10;
                bool myresult=false;

                if(abc==10)
                  myresult=true;
                else
                   myresult=false;
              }
            }");
        results.Errors.Cast<CompilerError>().ToList().ForEach(error => Console.WriteLine(error.ErrorText));
    }
}

我希望运行时代码在我的主程序中返回 myresult 变量的值以及如何获取它。

【问题讨论】:

  • 编译代码后,您可以简单地使用Process 类执行结果文件并从中捕获ExitCode。顺便说一句:然后您可以优化您的代码:Environment.Exit(abc == 10);
  • 我按照链接中给出的示例进行了尝试。但它仍然没有工作blackwasp.co.uk/RuntimeCompilation_2.aspx
  • @sia 遵循ShowExpressionResults 中的示例(在您的链接中),它加载已编译的程序集,在其中找到一个类,在类中找到一个方法并运行该方法并打印该方法的输出
  • 将再次尝试并更新结果..

标签: c# variables compiler-construction


【解决方案1】:

(1) 您可以将编译后的程序集加载为一段代码,并使用任何参数传递协定直接调用任何方法。以下修改后的示例打印

using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

class Program
{
    static void Main(string[] args)
    {
        var csc = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v3.5" } });
        var parameters = new CompilerParameters(new[] { "mscorlib.dll", "System.Core.dll" }, "Example.exe", true);
        parameters.GenerateExecutable = true;
        CompilerResults results = csc.CompileAssemblyFromSource(parameters,
        @"using System.Linq;
            class Program {
              public static void Main(string[] args) {}

              public static string Main1(int abc) {
                bool myresult=false;

                if(abc==10)
                  myresult=true;
                else
                  myresult=false;

                return abc.ToString() + "": "" + (myresult ? ""myresult is true"" : ""myresult is false"");
              }
            }");
        results.Errors.Cast<CompilerError>().ToList().ForEach(error => Console.WriteLine(error.ErrorText));

        var scriptClass = results.CompiledAssembly.GetType("Program");
        var scriptMethod1 = scriptClass.GetMethod("Main1", BindingFlags.Static | BindingFlags.Public);

        Console.WriteLine(scriptMethod1.Invoke(null, new object[] { 10 }).ToString());
        Console.WriteLine(scriptMethod1.Invoke(null, new object[] { 20 }).ToString());
    }
}

(2) 或者您可以使用您想要的任何命令行参数运行编译后的Example.exe,解析它们并以您想要的任何方式返回结果。控制台应用程序通常通过文件传达复杂的输入或输出结果,并通过Process.ExitCode 指示整体成功/失败。有很多可用的选项,其中一些在 Stack Overflow 问题 Returning a string from a console application

中进行了概述

【讨论】:

    【解决方案2】:

    您需要添加一个新的类似代码以使用“Example.exe”作为参考,并使用“Program”类来获取结果。此外,您将需要手动触发 main 并且应该有一个静态变量来存储结果。还需要在读取该变量之前保持该程序的完成。

    如果我理解正确,您正在编译和运行一个尚未创建的可执行文件。 这意味着,您需要假设它成功创建并在字符串中使用您的代码,并再创建一个可执行文件来运行它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-29
      • 1970-01-01
      • 1970-01-01
      • 2015-04-03
      • 2011-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多