C# 运行时编译CSharp。是否可以访问主程序';运行时代码中的s字段?

C# 运行时编译CSharp。是否可以访问主程序';运行时代码中的s字段?,c#,compilation,runtime,C#,Compilation,Runtime,这是我的密码: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.CSharp; using System.CodeDom.Compiler; using System.Reflection; namespace ConsoleApplication1 { class Program { public int

这是我的密码:

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


namespace ConsoleApplication1
{
    class Program
    {
        public int xx = 1; // variable I want to access from the runtime code

        static void Main(string[] args)
        {            
            CSharpCodeProvider provider = new CSharpCodeProvider();
            CompilerParameters parameters = new CompilerParameters();
            parameters.GenerateInMemory = true;
            parameters.ReferencedAssemblies.Add("System.dll");


            CompilerResults results = provider.CompileAssemblyFromSource(parameters, GetCode());
            var cls = results.CompiledAssembly.GetType("ConsoleApplication1.Program");
            var method = cls.GetMethod("DynamicMethod", BindingFlags.Static | BindingFlags.Public);
            method.Invoke(null, null);

            int a = int.Parse(Console.ReadLine()); // pause console
        }       


        static string[] GetCode()
        {
            return new string[]
            {
            @"using System;

            namespace ConsoleApplication1
            {
                class Program
                {
                    public static void DynamicMethod()
                    {                        
                        Console.WriteLine(""Hello, world!"");
                    }
                }
            }"
            };
        }
    }
}
我想知道是否可以从运行时代码中访问变量intxx(例如,将xx=2;行放在“hello world”之后)。那太棒了
谢谢:)

是的,您可以提供,但您需要:

  • 添加对包含
    xx
    的程序集的引用(为了方便起见,我将此程序集称为
    StaticAssembly
    ,因此可能是
    StaticAssembly.exe
    ,正在运行的控制台exe)
  • StaticAssembly
    a
    public
    类型中设置
    Program
    ,以便可以访问它
  • xx
    设置为
    静态
    字段,或者实例化
    程序的实例
    并以某种方式将其传递给动态代码
例如,以下方法很有效(我使用“实例化一个实例并传递它”的方法,因此我在
DynamicMethod
中添加了一个参数):


没有
int xx
xx
是一个实例字段,但没有类
程序的实例。至少,您需要将其设置为一个
静态
字段。另外,您的
ConsoleApplication1.Program
创建了另一个
ConsoleApplication1.Program
类,这让人非常困惑。它们具有相同的名称空间和名称,但仍然是不同的类型。您的第二个
控制台应用程序1。程序
没有第一个的字段。@hvd或使
程序
的实例在某些情况下可用于动态代码way@MarcGravell当然,这也行。介意我举一个简单的例子说明这个应该是什么样子吗P我尝试将int xx更改为静态字段,将运行时类名更改为Program2,然后将运行时代码中的Program.xx值更改为3,但它似乎不起作用。您可以告诉我这样做的方法吗?:“将StaticAssembly中的程序设置为公共类型,以便它可以访问”?示例“无法加载文件或程序集”中存在错误file:///C:\Users\Arbuz\AppData\Local\Temp\ulmdtb2g.dll'或其依赖项之一。'在此行中'var cls=results.CompiledAssembly.GetType(“GeneratedAssembly.Program”);'@这可能意味着您的静态程序集不是“StaticAssembly.exe”。检查
结果。错误
以了解更多信息。@Patryk re“public type”-参见我的示例中,我将
public
关键字添加到
StaticAssembly.Program
using System;
using System.CodeDom.Compiler;
using System.Reflection;
using Microsoft.CSharp;


namespace StaticAssembly
{
    public class Program
    {
        public int xx = 1; // variable I want to access from the runtime code

        static void Main(string[] args)
        {
            CSharpCodeProvider provider = new CSharpCodeProvider();
            CompilerParameters parameters = new CompilerParameters();
            parameters.GenerateInMemory = true;
            parameters.ReferencedAssemblies.Add("System.dll");
            parameters.ReferencedAssemblies.Add("StaticAssembly.exe");

            CompilerResults results = provider.CompileAssemblyFromSource(parameters, GetCode());
            var cls = results.CompiledAssembly.GetType("GeneratedAssembly.Program");
            var method = cls.GetMethod("DynamicMethod", BindingFlags.Static | BindingFlags.Public);
            var p = new Program();
            p.xx = 42;
            method.Invoke(null, new object[] {p});

            int a = int.Parse(Console.ReadLine()); // pause console
        }


        static string[] GetCode()
        {
            return new string[]
            {
            @"using System;

            namespace GeneratedAssembly
            {
                class Program
                {
                    public static void DynamicMethod(StaticAssembly.Program p)
                    {                        
                        Console.WriteLine(p.xx);
                        Console.WriteLine(""Hello, world!"");
                    }
                }
            }"
            };
        }
    }
}