gpt4 book ai didi

c# - 是否可以为动态 if 语句创建表达式树?

转载 作者:太空狗 更新时间:2023-10-29 20:28:25 25 4
gpt4 key购买 nike

我有一个场景,我在其中读取业务逻辑并将变量替换为实际值,然后我需要对其进行评估以获得结果。我目前正在使用 bcParser 来完成它,它适用于所有以 excel 格式编写的逻辑。

抛给我的曲线球是,if 条件不会像 excel if(cond, true, false) 而是像 C#,其中 if (cond) { 真的; } else { false;},这更有意义并且易于维护。因为我事先用值替换了所有变量,所以我所要做的就是评估它。目前我正在通过将逻辑导出到 c# 方法并使用反射来解决这个问题我正在评估它并且它也有效。

我想知道是否还有其他选择,我不想为每个 if 条件编写代码,而是想在运行时对其进行评估。我想知道我是否应该能够创建某种 token 解析器并调用 C# native 表达式评估并执行计算。我还没有深入了解表达式树,看来这种方法是可行的。在我去那里之前,我想知道这可能吗?谢谢,

最佳答案

是的!

关键是使用 System.Linq.Expressions 命名空间。您可以在代码中或通过修改解析器以编程方式构建表达式树,然后将其编译为 Delegate。此 API 在 DynamicAssembly 中编译您的 Delegate,这意味着当您完全取消引用它们时,垃圾收集器可以从内存中卸载已编译的表达式。

这是一个非常简单的例子:

var b = true;
Func<bool> condition = () => b;
Action trueExpression = () => { Console.WriteLine(true); };
Action falseExpression = () => { Console.WriteLine(false); };

var e = Expression.Condition(
Expression.Invoke(Expression.Constant(condition)),
Expression.Invoke(Expression.Constant(trueExpression)),
Expression.Invoke(Expression.Constant(falseExpression)));

var λ = Expression.Lambda(e).Compile();

b = true;
λ.DynamicInvoke();

b = false;
λ.DynamicInvoke();

这会产生输出:

True
False

将表达式编译成 Lambda 的步骤可能会严重影响性能,您需要为已编译的 Lambda 制定缓存策略。不过这是非常值得的,使用 DynamicInvoke 调用已编译的 lambda 非常快。几乎和预编译一样快。这种技术比使用 CodeDom 代码生成(这需要一个完整的过程来进行编译)要快得多,并且它具有生成可卸载程序集的主要好处。

唯一的限制是您不能使用此 API 创建类型。你必须将自己限制在表达和陈述中。然而,它非常强大,这就是 DLR 的神奇内脏。

关于c# - 是否可以为动态 if 语句创建表达式树?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9844599/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com