You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在运行时计算表达式参数?扩展规则引擎支持嵌套计算

扩展现有表达式树引擎支持计算式Target

首先要纠正一个小误解:表达式树不仅是可视化的数据结构,它本身就是可以编译成可执行代码的,你之前的实现已经在这么做了——现在只需要把Target字段里的计算式也转换成表达式树,和原有的成员表达式组合起来就行。下面分两部分解决你的问题:

一、扩展代码解析Target中的计算表达式

原来的代码把Target直接转成常量Expression.Constant,现在我们需要把Target的字符串(比如"30/2")解析成可执行的表达式树,再合并到规则表达式中。最省心的方式是用System.Linq.Dynamic.Core这个NuGet包,它能直接将字符串表达式转换成.NET表达式树,支持常见的算术运算、逻辑运算甚至对象属性引用。

步骤1:安装NuGet包

先安装System.Linq.Dynamic.Core:

Install-Package System.Linq.Dynamic.Core

步骤2:修改BuildExpr方法

修改原来的BuildExpr方法,把Target字符串解析成表达式,而不是直接转常量:

static Expression BuildExpr<T>(Rule r, ParameterExpression param)
{
    var left = MemberExpression.Property(param, r.MemberName);
    var tProp = typeof(T).GetProperty(r.MemberName).PropertyType;

    // 解析Target中的计算表达式:支持纯计算式(如"30/2")或引用对象属性(如"Age + 5")
    var targetExpr = DynamicExpressionParser.ParseLambda(
        parameters: new[] { param },
        resultType: tProp,
        expression: r.TargetValue);
    var right = targetExpr.Body;

    ExpressionType tBinary;
    if (ExpressionType.TryParse(r.Operator, out tBinary))
    {
        // 构建二元运算表达式,比如u.Age > (30/2)
        return Expression.MakeBinary(tBinary, left, right);
    }
    else
    {
        var method = tProp.GetMethod(r.Operator);
        var tParam = method.GetParameters()[0].ParameterType;
        // 转换表达式类型以匹配方法参数
        right = Expression.Convert(right, tParam);
        // 构建方法调用表达式,比如u.Tags.Contains(Age + 10)
        return Expression.Call(left, method, right);
    }
}

这样,当Target是"(30 / 2)"时,DynamicExpressionParser会把它转换成对应的除法表达式树,最终生成的规则就是u.Age > (30/2),完全符合你的需求。如果以后需要更复杂的Target(比如引用用户对象的其他属性"Age + 5"),这个代码也能直接支持。

手动解析表达式(可选)

如果不想引入第三方库,也可以自己写一个简单的表达式解析器,处理加减乘除和括号。不过这需要实现词法分析和语法分析,比较繁琐,适合对依赖有严格要求的场景。比如可以用递归下降法实现一个小型解析器,把字符串转换成表达式树。

二、现成规则引擎推荐

如果不想自己维护规则引擎的复杂逻辑,有几个成熟的.NET规则引擎可以考虑:

  • RulesEngine:微软维护的轻量规则引擎,支持从JSON/XML加载规则,也支持复杂表达式和嵌套条件,非常适合业务规则动态配置的场景。
  • NRules:基于.NET的规则引擎,支持正向链推理,适合复杂的业务规则场景,规则可以用代码或者DSL定义。
  • EasyRules:轻量、易扩展的规则引擎,支持注解式规则定义,适合简单到中等复杂度的规则场景。
  • System.Linq.Dynamic.Core:严格来说它不是完整的规则引擎,但它的表达式解析能力已经能覆盖大部分简单到中等的规则需求,像你现在的场景用它扩展就足够了。

这些引擎都支持动态加载规则、复杂表达式计算,能节省你自己造轮子的时间。

内容的提问来源于stack exchange,提问作者Gillan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:22:48