c# - 从字符串到方法

标签 c# delegates expression-trees

简短的问题, .NET 4.0 中是否有一种方法可以获取表示方法主体的字符串,并将其编译为 Func/Action,或者是否有库可以这样做?

澄清:

我需要一些不会生成任何dll的东西,它需要完全动态,就像javascript中的eval()。我需要将字符串转换为 Func/Action,而不创建 dll。

最佳答案

您可以使用CSharpCodeProvider class将源代码编译成程序集。

例如:

var compiler = new CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v4.0" } });
var options = new CompilerParameters { OutputAssembly = path);
var results = compiler.CompileAssemblyFromFile(options, sourceFile);

要编译单个函数,您可以使用适当的 using 语句将其包装在一个类中,以创建完整的源文件,然后使用反射获取委托(delegate):

var assembly = results.CompiledAssembly;
var method = assembly.GetType("WrapperClassName").GetMethod("MethodName");
var delegate = (Action)Delegate.CreateDelegate(typeof(Action), method);

对于 more complete example :

static readonly Assembly[] References = new[] { typeof(Enumerable).Assembly, typeof(Component).Assembly };
public Action CompileMethodstring source) {
    var options = new CompilerParameters(References.Select(a => a.Location).ToArray()) {
        GenerateInMemory = true
    };
    string fullSource = @"public static class HolderClass { public static void Execute() { \r\n" + source + "\r\n} }";
    try {
        var compiler = new CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v4.0" } });

        var results = compiler.CompileAssemblyFromSource(options, fullSource);

        if (results.Errors.Count > 0)
            throw new InvalidOperationException(String.Join(
                Environment.NewLine, 
                results.Errors.Cast<CompilerError>().Select(ce => ce.ErrorText)
            ));

        return (Action)Delegate.CreateDelegate(
            typeof(Action),
            results.CompiledAssembly.GetType("HolderClass").GetMethod("Execute")
        );
    } finally { options.TempFiles.Delete(); }
}

关于c# - 从字符串到方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4886744/

相关文章:

C#:调整大小时无法更新控件高度

c# - 在 Linq 表达式主体中如何使用变量的值而不是对它的引用?

c# - C#中设置匿名函数的参数值

c# - 通过表达式调用可枚举平均值

c# - 如何使用 Expression<Func> 设置嵌套属性?

c# - 将全选快捷方式 (Ctrl + A) 添加到 .net ListView ?

c# - ASP.NET Core MVC MySQL 标识

swift - 如何将数据传回 Watchkit 中的接口(interface) Controller

c# - 如何在 C# 中分配委托(delegate)扩展方法?

Linq where 关键字与 Where 扩展和表达式参数