当前位置:  开发笔记 > 编程语言 > 正文

将字符串解析为C#lambda Func

如何解决《将字符串解析为C#lambdaFunc》经验,为你挑选了3个好方法。

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

Func func = Parse("product => product.Name.Length > 0");

我尝试了动态LINQ但它没有按预期工作 - 例如它不期望lambda语法=>.

答案摘要:

编写我自己的C#编译器 - 非常有趣

启动外部编译器(如csc.exe) - 非常慢

使用DLINQ - 正如我所说,我不知道它如何解析lambda表达式

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

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

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



1> Prasad Kanap..:

它们是许多可用的lambda表达式解析器.其中一些是Lambda-Parser,Sprache

示例代码:

例1:字符串concat和数字计算:

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



2> tvanfosson..:

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


多么奇怪的顾客.:)
我想花时间在它上面可能会很有趣但不是我的客户 - 他们不会付钱给我编写C#编译器.

3> erikkallen..:

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

class ExpressionContainer {
    public Expression> TheExpression;
    public string Length;

    public ExpressionContainer() {
        TheExpression = ;
    }
}

然后做这样的事情:

string source = ;
Assembly a;
using (CSharpCodeProvider provider = new CSharpCodeProvider(...) {
    List assemblies = new List();
    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().Select(e => e.ErrorText).ToArray()));
    a = r.CompiledAssembly;
}
object o = a.CreateInstance("ExpressionContainer");
var result = ( Expression>)o.GetType().GetProperty("TheExpression").GetValue(o);

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

推荐阅读
落单鸟人
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有