c# - 是否可以执行以字符串表示的 C# 代码?

标签 c# string interpreter

在我的表单上,我点击了一个按钮

private void button1_Click(object sender, EventArgs e)
{
    do something                           
}

单击时如何从文本文件加载我的操作,例如我的文本文件如下所示:

MessageBox.Show("hello");
label1.Text = "Hello";

如果可能的话,单击它会执行我的文本文件中的所有操作。

最佳答案

这是一个非常简单的例子,只是为了证明这是可能的。基本上,您使用 CodeDomProvider在运行时编译源代码,然后使用反射执行。

var provider = CodeDomProvider.CreateProvider("C#");
string src=@"
    namespace x
    {
        using System;
        public class y
        {
            public void z()
            {
                Console.WriteLine(""hello world"");
            }
        }
    }
";
var result = provider.CompileAssemblyFromSource(new CompilerParameters(), src);
if (result.Errors.Count == 0)
{
    var type = result.CompiledAssembly.GetType("x.y");
    var instance = Activator.CreateInstance(type);
    type.GetMethod("z").Invoke(instance, null);
}

编辑

正如@Agat指出的,OP似乎需要一种脚本框架(它使用label1,当前对象的属性),而我上面的答案显然没有提供这一点。我能想到的最好的解决方案是一个有限的解决方案,这将要求将依赖项明确指定为“脚本”中的参数。例如,编写如下脚本代码:

string src = @"
namespace x
{
    using System.Windows;
    public class y
    {
        public void z(Label label1)
        {
            MessageBox.Show(""hello"");
            label1.Text = ""Hello"";
        }
    }
}
";

现在您可以让调用者检查参数,并再次使用反射从当前上下文传递它们:

var result = provider.CompileAssemblyFromSource(new CompilerParameters(), src);
if (result.Errors.Count == 0)
{
    var type = result.CompiledAssembly.GetType("x.y");
    var instance = Activator.CreateInstance(type);
    var method = type.GetMethod("z");
    var args = new List<object>();

    // assume any parameters are properties/fields of the current object
    foreach (var p in method.GetParameters())
    {
        var prop = this.GetType().GetProperty(p.Name);
        var field = this.GetType().GetField(p.Name);
        if (prop != null)
            args.Add(prop.GetValue(this, null));
        else if (field != null);
            args.Add(field.GetValue(this));
        else
            throw new InvalidOperationException("Parameter " + p.Name + " is not found");
    }
    method.Invoke(instance, args.ToArray());
}

关于c# - 是否可以执行以字符串表示的 C# 代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21445147/

相关文章:

c# - aspx 页面中的内联 C# 代码

c# - 解析具有相同名称元素的复杂 XML

javascript - 如何在不在服务器上创建页面的情况下将字符串解释为 HTML 页面

haskell - Haskell 解释器/w 类型定义

design-patterns - 忽略(严重)错误以使程序继续运行?

c# - 如何在 HttpModule 中执行 XSLT 转换?

c# - 我可以在单元测试中写入控制台吗?如果是,为什么控制台窗口不打开?

android - 在 Android 应用程序上显示其他语言文本

c - tolower() 和 toupper() 不起作用

自定义 Lua 字节码解释器的 LuaJIT 与 luac