Nếu bạn biết loại biểu thức trước thời hạn, thì bạn có thể biên dịch chúng thành một phần của một lớp rồi kéo chúng ra khỏi tập hợp kết quả.
Dưới đây là ví dụ thực hiện (với các biểu thức lấy một chuỗi và trả về một bool) và chạy các quy tắc kết quả.
Với các nội dung của c: \ temp \ rules.txt bị này:
file => file.Length == 0
file => System.IO.Path.GetExtension(file) == ".txt"
file => file == null
Sau đó, kết quả đầu ra là thế này:
Rules found in file:
file => file.Length == 0,
file => System.IO.Path.GetExtension(file) == ".txt",
file => file == null,
Checking rule file => (file.Length == 0) against input c:\temp\rules.txt: False
Checking rule file => (GetExtension(file) == ".txt") against input c:\temp\rules.txt: True
Checking rule file => (file == null) against input c:\temp\rules.txt: False
Nguồn:
using System;
using System.Xml.Linq;
using System.Linq;
using System.IO;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Reflection;
using System.Linq.Expressions;
class Program
{
private const string classTemplate = @"
using System;
using System.Linq.Expressions;
public static class RulesConfiguration
{{
private static Expression<Func<string, bool>>[] rules = new Expression<Func<string, bool>>[]
{{
{0}
}};
public static Expression<Func<string, bool>>[] Rules {{ get {{ return rules; }} }}
}}
";
static void Main(string[] args)
{
var filePath = @"c:\temp\rules.txt";
var fileContents = File.ReadAllLines(filePath);
// add commas to the expressions so they can compile as part of the array
var joined = String.Join("," + Environment.NewLine, fileContents);
Console.WriteLine("Rules found in file: \n{0}", joined);
var classSource = String.Format(classTemplate, joined);
var assembly = CompileAssembly(classSource);
var rules = GetExpressionsFromAssembly(assembly);
foreach (var rule in rules)
{
var compiledToFunc = rule.Compile();
Console.WriteLine("Checking rule {0} against input {1}: {2}", rule, filePath, compiledToFunc(filePath));
}
}
static Expression<Func<string, bool>>[] GetExpressionsFromAssembly(Assembly assembly)
{
var type = assembly.GetTypes().Single();
var property = type.GetProperties().Single();
var propertyValue = property.GetValue(null, null);
return propertyValue as Expression<Func<string, bool>>[];
}
static Assembly CompileAssembly(string source)
{
var compilerParameters = new CompilerParameters()
{
GenerateExecutable = false,
GenerateInMemory = true,
ReferencedAssemblies =
{
"System.Core.dll" // needed for linq + expressions to compile
},
};
var compileProvider = new CSharpCodeProvider();
var results = compileProvider.CompileAssemblyFromSource(compilerParameters, source);
if (results.Errors.HasErrors)
{
Console.Error.WriteLine("{0} errors during compilation of rules", results.Errors.Count);
foreach (CompilerError error in results.Errors)
{
Console.Error.WriteLine(error.ErrorText);
}
throw new InvalidOperationException("Broken rules configuration, please fix");
}
var assembly = results.CompiledAssembly;
return assembly;
}
}
Nguồn
2012-01-14 07:54:27
Có thể trùng lặp? [http://stackoverflow.com/questions/714799/is-there-an-easy-way-to-parse-a-lambda-expression-string-into-an-action-delega](http://stackoverflow. com/questions/714799/is-there-an-easy-way-to-parse-a-lambda-biểu-chuỗi-thành-một-hành động-delega) – MNIK
Có thể có liên quan: http://stackoverflow.com/questions/ 8327831/có thể-net-được-phân tích cú pháp-và-đánh giá-tại-thời gian chạy/8328096 # 8328096 – sehe
Bỏ phiếu để đóng. Lưu ý phụ: xem xét nhiều ngôn ngữ thân thiện với kịch bản hơn cho LUA logic của bạn (http://stackoverflow.com/questions/1283641/lua-wrapper-for-c), IronPython, –