C# 从字符串到方法

C# 从字符串到方法,c#,delegates,expression-trees,C#,Delegates,Expression Trees,简短的问题, 在.NET 4.0中,是否有方法获取表示方法体的字符串,并将其编译为Func/Action,或者是否有一个库可以这样做 澄清: 我需要一些不会生成任何dll的东西,它需要是完全动态的,比如javascript中的eval()。我需要在不创建dll的情况下将字符串转换为Func/Action。您可以使用将源代码编译成程序集 例如: var compiler = new CSharpCodeProvider(new Dictionary<string, string> {

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

澄清:

我需要一些不会生成任何dll的东西,它需要是完全动态的,比如javascript中的eval()。我需要在不创建dll的情况下将字符串转换为Func/Action。

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

例如:

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

static readonly Assembly[]References=new[]{typeof(可枚举).Assembly,typeof(组件).Assembly};
公共行动编译器方法字符串(源代码){
var options=新编译器参数(References.Select(a=>a.Location.ToArray()){
GenerateInMemory=true
};
字符串fullSource=@“公共静态类HolderClass{public static void Execute(){\r\n“+source+”\r\n}}”;
试一试{
var compiler=new CSharpCodeProvider(新字典{{“compilervision”,“v4.0”});
var results=compiler.compileasemblyfromsource(选项,fullSource);
如果(results.Errors.Count>0)
抛出新的InvalidOperationException(String.Join(
环境,新线,
results.Errors.Cast().Select(ce=>ce.ErrorText)
));
返回(操作)委托。CreateDelegate(
类型(动作),
results.CompiledAssembly.GetType(“HolderClass”).GetMethod(“Execute”)
);
}最后{options.TempFiles.Delete();}
}
可能就是您要找的。但是,您需要创建有效的C#代码(也就是说,您需要为该方法创建一个类)。

您还可以使用它作为嵌入式脚本平台,您还可以执行以下操作:

dynamic script = CSScript.LoadCode(@"using System;
                                     public class Script
                                     {
                                         public void SayHello(string greeting)
                                         {
                                             Console.WriteLine(greeting);
                                         }
                                     }")
                                    .CreateObject("*");
script.SayHello("Hello World!");

我已经在生产中使用了将近2年,这是创建可配置应用程序的一种很好的方法。如果您感兴趣,我有一个解决方案。

您是指JavaScript对eval()所做的事情吗?您是在寻找运行时解决方案还是设计时解决方案?如果是后者,您可以始终使用代码生成模板,如MyGeneration或T4?如果是前者,你看过Microsoft.CSharp和System.CodeCom.Compiler名称空间吗?实际上,这可能行得通,我只需要做一点代码生成。这看起来很有希望。你知道它在中等信任度下是否有效吗?据我所知,是的。以下是指向它支持的脚本模型的链接:。Oleg项目负责人反应非常积极,如果有其他问题,你可以随时与他联系。
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(); }
}
dynamic script = CSScript.LoadCode(@"using System;
                                     public class Script
                                     {
                                         public void SayHello(string greeting)
                                         {
                                             Console.WriteLine(greeting);
                                         }
                                     }")
                                    .CreateObject("*");
script.SayHello("Hello World!");