开发者

from string to method

开发者 https://www.devze.com 2023-02-08 13:28 出处:网络
Short question, Is there a way in .NET 4.0 to take a string that represents the method body, and compile it into a Func/Action, or is there a library to do so?

Short question, Is there a way in .NET 4.0 to take a string that represents the method body, and compile it into a Func/Action, or is there a library to do so?

Clarification:

I need something that will not generate any dll, it needs to be comple开发者_如何学JAVAtely dynamic, something like eval() in javascript. I need to convert string into a Func/Action without creating dll.


You can use the CSharpCodeProvider class to compile source code into an assembly.

For example:

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

To compile a single function, you can wrap it in a class with appropriate using statements to create a complete source file, then get a delegate using Reflection:

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

For a 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(); }
}


You could also use CS-Script.Net It is an embedded scripting platform that also you to do the following:

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

I've been using in production for almost 2 years now and it has been a great way to create configurable applications. I have a sample project if you are interested.


The CSharpCodeProvider might be what you are looking for. However, you'll need to create valid C# code (meaning, you'll need to create a class for that method).

0

精彩评论

暂无评论...
验证码 换一张
取 消