简短的问题, .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);
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/