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

2023-12-25

我有一种情况,我读取业务逻辑并将变量替换为实际值,然后我需要对其进行评估以获得结果。我目前正在使用 bcParser 来执行此操作,它对于所有像 excel 格式一样编写的逻辑都可以正常工作。

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

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


Yes!

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

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

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 的神奇之处。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否可以为动态 if 语句创建表达式树? 的相关文章

随机推荐

  • 将映像包含在可执行 jar 中

    我一整天都在浏览 Stackoverflow 寻找如何做到这一点 但还没有成功 我正在将我制作的快速游戏打包成可执行 jar 但我没有正确引用图像 我只是引用了文件 background ImageIO read new File wood
  • 将 json 对象存储到 Azure blob 存储

    有没有办法存储 json 对象而不将其转换为流 我可以将其转换为流后上传 但是是否有任何方法可以将对象存储为 something json 而不将其转换为流 我现在应该做什么 const azureStorage require azure
  • OOP在大学里被滥用了吗? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我两年前开始上大学 从那时起我一直听到 首先设计你的课程 有时我真的会问自己 我的解决方案首先应该是一堆对象吗 有人说你看不到它的好处 因为你的
  • 显示 Android 中按下按钮后经过的时间

    我希望能够在 统计 类中的文本视图或计时器中显示自按下另一个类中的按钮以来经过的时间 实现这个最简单的方法是什么 Thanks 设置变量怎么样 System currentTimeMillis 当你膨胀视图时 在 onDestroy 处从当
  • 更改 LazyRow 上的滚动速度

    查看文档LazyRow我想知道是否可以降低滚动速度 看起来像LazyRow继承自ScrollState但我找不到任何关于如何降低滚动速度的有用信息 LazyRow 没有用于自定义滚动速度的参数 因此您必须手动执行此操作 您可以首先捕获类似于
  • Apollo GraphQL - 将 .graphql 架构导入为 typeDefs

    使用 graphql yoga 您可以通过执行以下操作简单地导入模式 typeDefs src schema graphql apollo server express 是否有类似的方法 如果没有 如何从外部导入 typeDefs grap
  • Android XML:RuntimeException:无法解析索引 6 处的属性

    你好亲爱的stackoverflower 在我的项目中 我使用新的 android 设计库 问题是 有一个运行时异常 我正在尝试创建一个浮动按钮 java lang RuntimeException Failed to resolve at
  • 将一个堆栈推入另一个堆栈

    在 C 中 有没有一种方法可以将一个堆栈压入另一个堆栈 而无需迭代堆栈元素 如果没有 我应该使用更好的数据结构吗 在Java中你可以这样做 stack1 addAll stack2 我希望找到 C 的类似物 0 安全解决方案 扩展方法 pu
  • 替换()与“[<-”?

    我最近偶然发现replace and lt 它们似乎具有相似的功能 例如 lt 我可以做这样的事情 gt x tst lt array 1 6 c 2 3 gt s tst lt array 0 c 2 3 gt s tst 1 2 3 1
  • 无法通过 MavenCli (maven-embedder) 运行 Maven 任务

    我在程序中使用 Maven embedder 3 3 3 以编程方式运行 Maven 目标 每次运行时都会出现以下错误MavenCli doMain method Dmaven multiModuleProjectDirectory系统属性
  • 通过 OKTA SAML 单点注销

    我收到以下 SP 请求和 IDP 响应
  • android css 背景图像未找到

    我正在尝试使用图像纹理作为我的网页主体背景 我的网页显示在 Android 网络视图中 这是我的CSS body font family helvetica font size 12px color 555555 padding 10px
  • Ansible 正则表达式匹配字符串并提取行

    我试图在一行中的 1 个空格之后找到一个字符串 如果存在 则提取完整的行并存储在不同的变量中 我正在使用 ansible 和正则表达式 如果该字符串存在于任何其他位置 则不应匹配它 我尝试使用 regex match 和 select 但出
  • Spring授权和资源在同一台服务器上

    我是 spring 环境的新手 我刚刚学习 oauth2 有没有办法让授权服务器也成为资源服务器 我正在看这个新项目https github com spring projects spring authorization server h
  • 模拟 ViewContext 来测试验证错误消息

    故事是这样的 为了能够将格式良好的 Bootstrap 控件放入我的 MVC 表单中 我正在构建一个HtmlHelper扩展方法 使用单个命令生成以下结构 div class control group Html LabelFor m gt
  • MSI 安装程序失败且未删除以前的安装

    我已经构建了一个我想要部署并经常更新的 MSI 不幸的是 当您安装 MSI 然后尝试安装同一 MSI 的较新版本时 它会失败 并显示类似 已安装此产品的另一个版本 此版本的安装无法继续 的消息 MSI 是使用 Visual Studio 2
  • 从结构句柄的 System::String^ 成员编组到 std::string

    我正在尝试从 System String 编组到 std string 通常这可以通过marshal as
  • 运行 Docker 镜像时无法访问 jarfile

    我是 Spring Boot 微服务和 Docker 的新手 微服务项目中的dockerfile 码头工人构建 泊坞窗图像 运行镜像时出现错误 无法访问jarfile register server jar 干杯 肖恩 您需要指定绝对目标路
  • 在Spring MVC中,使用@ResponseBody时如何设置mime类型标头

    我有一个返回 JSON 字符串的 Spring MVC 控制器 我想将 mimetype 设置为 application json 我怎样才能做到这一点 RequestMapping method RequestMethod GET val
  • 是否可以为动态 if 语句创建表达式树?

    我有一种情况 我读取业务逻辑并将变量替换为实际值 然后我需要对其进行评估以获得结果 我目前正在使用 bcParser 来执行此操作 它对于所有像 excel 格式一样编写的逻辑都可以正常工作 向我抛出的曲线球是 if 条件不会像 excel