.NET Core 5环境下如何实现C#动态where运算符的自定义规则匹配?
.NET Core 5完全支持这类动态条件查询,以下是两种可直接落地的实现方案:
方案1:原生表达式树实现(无第三方依赖)
基于.NET原生的表达式树API实现,不需要引入任何外部包,性能稳定可控。
首先实现规则判断的工具类:
using System.Linq.Expressions; public static class RuleEvaluator { public static bool Match(Foo foo, RuleStatement rule) { // 构建左值:Foo实例的Value属性 var leftExp = Expression.Property(Expression.Constant(foo), nameof(Foo.Value)); // 构建右值:规则指定的比较值 var rightExp = Expression.Constant(rule.Value); // 根据运算符生成对应比较表达式 Expression compareExp = rule.Operator switch { "==" => Expression.Equal(leftExp, rightExp), "!=" => Expression.NotEqual(leftExp, rightExp), ">" => Expression.GreaterThan(leftExp, rightExp), ">=" => Expression.GreaterThanOrEqual(leftExp, rightExp), "<" => Expression.LessThan(leftExp, rightExp), "<=" => Expression.LessThanOrEqual(leftExp, rightExp), _ => throw new NotSupportedException($"暂不支持运算符:{rule.Operator}") }; // 编译表达式并执行返回结果 return Expression.Lambda<Func<bool>>(compareExp).Compile()(); } }
你的业务逻辑可以直接修改为:
bool isMatch = rules.All(rule => source.Any(s => s.Path == rule.Path && RuleEvaluator.Match(s, rule)));
优化提示:如果规则调用频率很高,可以将编译后的比较委托按运算符+比较值做缓存,避免重复编译的性能开销,优化后性能和硬编码判断几乎一致。
方案2:动态Linq库实现(代码更精简)
如果可以引入第三方包,使用官方生态维护的System.Linq.Dynamic.Core库可以大幅简化代码,支持更丰富的动态规则场景。
- 首先安装NuGet包:
Install-Package System.Linq.Dynamic.Core
- 直接调用动态Linq的扩展方法即可:
using System.Linq.Dynamic.Core; // 参数化写法避免特殊字符问题,更安全 bool isMatch = rules.All(rule => source.Any("Path == @0 && Value " + rule.Operator + " @1", rule.Path, rule.Value));
两种方案都可以完美匹配你的测试场景:场景1返回true,场景2返回false,完全符合预期。
内容的提问来源于stack exchange,提问作者Tiago B
相关产品推荐
相关产品推荐

