使用IComparer实现多字段排序,如何优化现有繁琐的实现代码?
现有代码问题提示
首先你现有代码存在一个隐性bug:CName和FName的比较逻辑中,右侧的比较对象错误写成了this,实际应为传入的mod对象,会导致这两个字段的排序完全失效。
优化方案
方案1:扁平化判断逻辑(兼容低版本C#)
去掉冗余的嵌套else结构,只要前一级比较结果不为0就直接返回,逻辑更清晰:
public int Compare(DataAccessViewModel x, DataAccessViewModel y) { return x?.CompareTo(y) ?? 0; } public int CompareTo(DataAccessViewModel mod) { if (mod == null) return 0; // 1. 优先比较PriorityScore int ret = (int)(PriorityScore?.CompareTo(mod.PriorityScore)); if (ret != 0) return ret; // 2. 比较MName ret = (MName ?? "zzzzzzzzzzzzz").CompareTo(mod.MName ?? "zzzzzzzzzzzzz"); if (ret != 0) return ret; // 3. 比较CName ret = (CName ?? "zzzzzzzzzzzzz").CompareTo(mod.CName ?? "zzzzzzzzzzzzz"); if (ret != 0) return ret; // 4. 最后比较FName return (FName ?? "zzzzzzzzzzzzz").CompareTo(mod.FName ?? "zzzzzzzzzzzzz"); }
方案2:ValueTuple 链式比较(C# 7.0+ 最简洁写法)
利用C#值元组默认按元素顺序依次比较的特性,完全不需要手动写判断分支,一行即可实现多优先级排序,和原有逻辑完全一致:
public int Compare(DataAccessViewModel x, DataAccessViewModel y) { return x?.CompareTo(y) ?? 0; } public int CompareTo(DataAccessViewModel mod) { if (mod == null) return 0; return (PriorityScore, MName ?? "zzzzzzzzzzzzz", CName ?? "zzzzzzzzzzzzz", FName ?? "zzzzzzzzzzzzz") .CompareTo((mod.PriorityScore, mod.MName ?? "zzzzzzzzzzzzz", mod.CName ?? "zzzzzzzzzzzzz", mod.FName ?? "zzzzzzzzzzzzz")); }
额外方案:临时排序用LINQ更方便
如果你不需要让类实现IComparable接口,只是临时对列表做排序,直接用LINQ的链式排序方法可读性更高:
var sortedList = dataList .OrderBy(x => x.PriorityScore) .ThenBy(x => x.MName ?? "zzzzzzzzzzzzz") .ThenBy(x => x.CName ?? "zzzzzzzzzzzzz") .ThenBy(x => x.FName ?? "zzzzzzzzzzzzz") .ToList();
以上所有方案都保留了你原有的逻辑:字段为null时排序在最后。
内容的提问来源于stack exchange,提问作者Pரதீப்
相关产品推荐
相关产品推荐

