重构条件判断与循环:基于角色名称高效排序用户的优化问询
解决方案
核心优化点
- 移除重复的
sortBy条件判断,简化分支逻辑 - 生成全角色排序键:将用户的所有角色名称按字母排序后,以此作为排序依据,实现基于所有角色的排序
- 用LINQ链式操作替代foreach循环,提升代码简洁性与执行效率
- 合并DTO转换与排序逻辑,避免重复的内存操作
重构后的代码
public List<UserDto> GetUsersSorted(string sortBy) { // 获取原始数据,简化分支判断 var usersCollection = sortBy == "roles" ? GetUnsortedUsers() // 原逻辑:不排序获取用户 : GetUsersSortedByOtherField(sortBy); // 原逻辑:按其他字段排序获取 // 统一处理DTO转换+角色内部排序 var items = usersCollection.Select(user => { var dto = new UserDto { Name = user.Name, Password = user.Password, // 映射其他属性... Roles = user.Roles.OrderBy(r => r.Name).ToList() // 先对用户自身的角色排序 }; return dto; }); // 按角色排序的专属逻辑 if (sortBy == "roles") { items = items.OrderBy(dto => // 用排序后的角色名称拼接字符串作为排序键,实现全角色维度排序 string.Join(",", dto.Roles.Select(r => r.Name)) ); } return items.ToList(); }
关键细节说明
- 全角色排序逻辑:通过
string.Join(",", dto.Roles.Select(r => r.Name))生成排序键,比如用户有角色["Admin", "Editor"]会被拼接为"Admin,Editor",另一个用户有["Editor", "Viewer"]则为"Editor,Viewer",排序时会按整个字符串的字典序比较,实现基于所有角色的排序。 - 分支简化:原代码两次判断
sortBy=='roles',现在仅保留一次排序分支,数据获取分支用三元表达式简化,减少冗余。 - LINQ替代foreach:用
Select操作合并原foreach循环的角色排序逻辑,一次遍历完成DTO转换与角色排序,减少内存迭代次数。
如果追求更高性能(避免字符串拼接开销),可以自定义比较器:
public class UserByRolesComparer : IComparer<UserDto> { public int Compare(UserDto x, UserDto y) { int minCount = Math.Min(x.Roles.Count, y.Roles.Count); for (int i = 0; i < minCount; i++) { int roleCompare = string.Compare(x.Roles[i].Name, y.Roles[i].Name, StringComparison.OrdinalIgnoreCase); if (roleCompare != 0) return roleCompare; } // 前面角色都相同时,角色数量多的排后面(可按需调整规则) return x.Roles.Count.CompareTo(y.Roles.Count); } } // 使用时替换OrderBy: items = items.OrderBy(dto => dto, new UserByRolesComparer());
这种方式避免了字符串拼接的性能损耗,适合用户或角色数量较多的场景。
内容的提问来源于stack exchange,提问作者DS Assignment
相关产品推荐
相关产品推荐

