首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >将字符串解析为C#λ函数

将字符串解析为C#λ函数
EN

Stack Overflow用户
提问于 2009-11-10 21:09:46
回答 5查看 25.8K关注 0票数 23

有没有办法将lambda的字符串表示转换为lambda Func?

Func<Product, bool> func = Parse<Product, bool>("product => product.Name.Length > 0");

我尝试过Dynamic LINQ,但是它不能像预期的那样工作--例如,它不需要lambda语法=>。

答案摘要:

  • 编写我自己的C#编译器-非常有趣的
  • 启动外部编译器(如csc.exe) -使用DLINQ的非常慢的
  • -正如我所说的,我不明白它如何解析λ表达式

<代码>F210

为什么我需要这样:因为没有办法将lambda传递给自定义属性,比如

[Secure(role => role.CanDoThis && role.AllowedCount > 5)]

因此,作为一种变通方法,我想将lambda作为字符串传递:"role => role.CanDoThis && role.AllowedCount > 5“。但似乎我必须这样使用DLINQ:"CanDoThis && AllowedCount > 5“--因为这是它能理解的语法。但我的问题是关于真正的lambdas,我在提问时已经使用了DLINQ。

EN

回答 5

Stack Overflow用户

发布于 2012-10-16 03:54:58

它们是许多可用的lambda表达式解析器。其中一些是Lambda-ParserSprache

示例代码:

Example1 :字符串拼接和数字计算:

string code = "2.ToString()+(4*2)"; // C# code Func<string> 
func = ExpressionParser.Compile<Func<string>>(code); // compile code 
string result = func(); // result = "28"
票数 9
EN

Stack Overflow用户

发布于 2009-11-10 21:17:47

您可以解析字符串并使用Expression类构建一个lambda表达式,本质上复制编译器的功能。

票数 7
EN

Stack Overflow用户

发布于 2009-11-10 22:16:29

我想你不得不求助于CSharpCodeProvider。但是,处理所有可能的局部变量引用可能并不容易。您将如何告诉CSharpCodeProvider有关lambda参数的类型?我可能会创建一个模板类,如下所示:

class ExpressionContainer {
    public Expression<Func<Product, bool>> TheExpression;
    public string Length;

    public ExpressionContainer() {
        TheExpression = <user expression text>;
    }
}

然后这样做:

string source = <Code from above>;
Assembly a;
using (CSharpCodeProvider provider = new CSharpCodeProvider(...) {
    List<string> assemblies = new List<string>();
    foreach (Assembly x in AppDomain.CurrentDomain.GetAssemblies()) {
        try {
            assemblies.Add(x.Location);
        }
        catch (NotSupportedException) {
            // Dynamic assemblies will throw, and in .net 3.5 there seems to be no way of finding out whether the assembly is dynamic before trying.
        }
    }

    CompilerResults r = provider.CompileAssemblyFromSource(new CompilerParameters(assemblies.ToArray()) { GenerateExecutable = false, GenerateInMemory = true }, source);
    if (r.Errors.HasErrors)
        throw new Exception("Errors compiling expression: " + string.Join(Environment.NewLine, r.Errors.OfType<CompilerError>().Select(e => e.ErrorText).ToArray()));
    a = r.CompiledAssembly;
}
object o = a.CreateInstance("ExpressionContainer");
var result = ( Expression<Func<Product, bool>>)o.GetType().GetProperty("TheExpression").GetValue(o);

但是,请注意,对于长时间运行的应用程序,您应该在单独的appdomain中创建所有这些内存中的程序集,因为在卸载它们所在的appdomain之前,它们不能被释放。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1707854

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档