能否修改Filter<T>函数以支持多属性比较及任意类型匹配?
多属性联合过滤的Filter实现方案
核心思路
通过表达式树动态构建多个属性的相等判断条件,并将这些条件用逻辑与(AndAlso)联合起来,最终生成Func<T, bool>作为Where方法的过滤委托,实现多属性、任意类型值的联合匹配。
1. 定义过滤条件类
先创建一个类来存储单个属性的过滤规则:
public class FilterCondition { // 要过滤的属性名称(需与目标类的属性名完全一致) public string PropertyName { get; set; } // 要匹配的属性值(支持任意类型,后续会自动转换为属性对应的类型) public object Value { get; set; } }
2. 实现扩展方法Filter
编写静态扩展方法,利用表达式树动态构建过滤逻辑:
using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; public static class FilterExtensions { public static IEnumerable<T> Filter<T>(this IEnumerable<T> source, List<FilterCondition> conditions) { // 参数校验 if (source == null) throw new ArgumentNullException(nameof(source)); if (conditions == null || !conditions.Any()) return source; // 定义表达式的输入参数:代表集合中的每个T类型对象(比如x => ... 中的x) var parameter = Expression.Parameter(typeof(T), "x"); Expression combinedCondition = null; foreach (var condition in conditions) { // 获取目标属性的表达式:x.PropertyName var propertyExpr = Expression.Property(parameter, condition.PropertyName); // 将匹配值转换为属性对应的类型(处理值类型装箱、类型不匹配问题) var typedValue = Convert.ChangeType(condition.Value, propertyExpr.Type); var constantExpr = Expression.Constant(typedValue); // 构建单个属性的相等判断表达式:x.PropertyName == Value var equalsExpr = Expression.Equal(propertyExpr, constantExpr); // 合并所有条件:多个条件用逻辑与(AndAlso)连接 combinedCondition = combinedCondition == null ? equalsExpr : Expression.AndAlso(combinedCondition, equalsExpr); } // 将联合条件转换为Lambda表达式:x => 所有条件的逻辑与结果 var filterLambda = Expression.Lambda<Func<T, bool>>(combinedCondition, parameter); // 应用过滤并返回结果 return source.Where(filterLambda); } }
3. 使用示例
假设我们有一个Person类,需要同时筛选FirstName=John且LastName=Smith的对象:
public class Person { public string FirstName { get; set; } public string LastName { get; set; } public int Age { get; set; } } // 测试代码 var peopleList = new List<Person> { new Person { FirstName = "John", LastName = "Smith", Age = 30 }, new Person { FirstName = "Jane", LastName = "Doe", Age = 25 }, new Person { FirstName = "John", LastName = "Doe", Age = 35 } }; // 定义多属性过滤条件 var filterRules = new List<FilterCondition> { new FilterCondition { PropertyName = "FirstName", Value = "John" }, new FilterCondition { PropertyName = "LastName", Value = "Smith" } }; // 执行过滤 var filteredPeople = peopleList.Filter(filterRules).ToList(); // 最终结果仅包含FirstName=John且LastName=Smith的Person对象
关键说明
- 支持任意类型的属性值:只要传入的
Value能转换为目标属性的类型(比如int、DateTime、bool等都可以直接使用) - 多属性联合匹配:所有传入的
FilterCondition会自动用逻辑与连接,实现"且"的筛选逻辑 - 表达式树动态构建:无需手动编写每个属性的过滤代码,完全根据传入的条件动态生成
内容的提问来源于stack exchange,提问作者snappymcsnap
相关产品推荐
相关产品推荐

