C# 基于Linq实现运行时未知类型IEnumerable的多条件动态排序问题
解决方案
你完全不需要提前初始化IOrderedEnumerable,多余的LINQ查询语法占位代码是你报错的核心原因,直接从第一个排序参数开始构造链式调用即可:
- 第一个排序参数调用
OrderBy/OrderByDescending,返回的结果本身就是IOrderedEnumerable<dynamic>类型 - 后续排序参数直接基于这个实例调用
ThenBy/ThenByDescending即可 - 提前缓存
PropertyInfo避免lambda中重复反射查询,提升性能 - 注意原方法的
dataToSort是值传递,修改方法内的变量不会影响外部传入的集合,如果你需要修改原始变量,要么给参数加ref关键字,要么把方法返回值改为IEnumerable<dynamic>返回排序后的结果
完整可运行代码
// 用ref参数确保外部能拿到修改后的排序结果,也可以改成返回IEnumerable<dynamic> public static void SortData(ref IEnumerable<dynamic> dataToSort, List<KeyValuePair<string, string>> sortArgs) { // 边界处理:无排序参数直接返回 if (sortArgs == null || sortArgs.Count == 0) { return; } Type dataType = TypeService.GetType(dataToSort); IOrderedEnumerable<dynamic> orderedQuery = null; for (int argIDX = 0; argIDX < sortArgs.Count; argIDX++) { var arg = sortArgs[argIDX]; var sortField = arg.Key.Trim(); var sortDirection = arg.Value.Trim().ToUpper(); // 校验属性是否存在,可按需调整异常/跳过逻辑 PropertyInfo prop = dataType.GetProperty(sortField); if (prop == null) { throw new ArgumentException($"类型{dataType.Name}中不存在指定排序属性{sortField}"); } if (argIDX == 0) { // 第一个排序条件直接生成IOrderedEnumerable实例 orderedQuery = sortDirection == "DESC" ? dataToSort.OrderByDescending(e => prop.GetValue(e)) : dataToSort.OrderBy(e => prop.GetValue(e)); } else { // 后续排序条件直接链式调用ThenBy系列方法 orderedQuery = sortDirection == "DESC" ? orderedQuery.ThenByDescending(e => prop.GetValue(e)) : orderedQuery.ThenBy(e => prop.GetValue(e)); } } // 执行排序并赋值 dataToSort = orderedQuery.ToList(); }
内容的提问来源于stack exchange,提问作者Gary O. Stenstrom
相关产品推荐
相关产品推荐

