.NET如何实现自定义列表按PrimaryItem、SecondaryItem层级排序
实现CustomObject嵌套属性排序的两种方案
你需要的先按PrimaryItem排序、同PrimaryItem分组下再按SecondaryItem排序的需求,在.NET平台下可以通过LINQ或者IComparable接口两种方式实现,都不需要修改原始数据生成逻辑,直接对拿到的集合操作即可。
方案1:LINQ 实现(无侵入,推荐新手使用)
这个方案不需要修改你现有的CustomObject和CustomObjectList类定义,只需要引入LINQ命名空间即可使用,适合不想改动原有实体代码的场景。
首先在代码文件顶部添加引用:
Imports System.Linq
方式1:生成新的排好序的集合
用OrderBy指定第一排序优先级的字段,后续用ThenBy追加次级排序字段,逻辑完全匹配你要的层级排序规则:
' 假设你已经拿到填充完数据的CustomObjectList实例,变量名为sourceList ' 先按PrimaryItem升序,同PrimaryItem下按SecondaryItem升序 Dim sortedQuery = sourceList. OrderBy(Function(item) item.PrimaryItem). ThenBy(Function(item) item.SecondaryItem) ' 因为CustomObjectList是自定义的List子类,需要手动转换为对应类型 Dim sortedList As New CustomObjectList() sortedList.AddRange(sortedQuery)
方式2:直接在原集合上排序
如果不需要保留原集合的乱序状态,可以直接用List自带的Sort方法,传入比较逻辑即可,不会生成新集合:
sourceList.Sort(Function(x, y) ' 先比较一级排序字段 Dim primaryCompareResult = String.Compare(x.PrimaryItem, y.PrimaryItem, StringComparison.Ordinal) If primaryCompareResult <> 0 Then Return primaryCompareResult ' 一级字段相等时比较二级字段 Return String.Compare(x.SecondaryItem, y.SecondaryItem, StringComparison.Ordinal) End Function)
方案2:实现IComparable接口(内置默认排序规则)
如果这个排序规则是CustomObject的通用排序逻辑,后续会在多处用到,可以直接让实体类实现IComparable(Of CustomObject)接口,把排序逻辑内置到类中,后续排序不需要重复写规则。
首先修改CustomObject类的定义,添加接口实现:
' 需要先引入System命名空间 Imports System Public Class CustomObject Implements IComparable(Of CustomObject) Private _primaryItem As String Private _secondaryItem As String Public Property PrimaryItem As String Get Return _primaryItem End Get Set(ByVal value As String) _primaryItem = value End Set End Property Public Property SecondaryItem As String Get Return _secondaryItem End Get Set(ByVal value As String) _secondaryItem = value End Set End Property ' 实现接口定义的比较方法 Public Function CompareTo(other As CustomObject) As Integer Implements IComparable(Of CustomObject).CompareTo ' 比较对象为空时,当前对象排在前面 If other Is Nothing Then Return 1 ' 优先比较一级属性 Dim primaryCompareResult = String.Compare(Me.PrimaryItem, other.PrimaryItem, StringComparison.Ordinal) If primaryCompareResult <> 0 Then Return primaryCompareResult End If ' 一级属性相等时比较二级属性 Return String.Compare(Me.SecondaryItem, other.SecondaryItem, StringComparison.Ordinal) End Function End Class
修改完成后,排序代码可以大幅简化:
' 原列表直接排序,不需要传入任何排序规则 sourceList.Sort() ' LINQ排序也可以省略排序键参数 Dim sortedList As New CustomObjectList() sortedList.AddRange(sourceList.Order())
注意事项
- 字符串比较时建议显式指定
StringComparison枚举参数,比如Ordinal为严格按字符编码顺序比较,和多数数据库默认排序逻辑一致;如果需要忽略大小写可以用OrdinalIgnoreCase,避免因当前线程区域文化设置导致排序结果不符合预期。 - 如果需要倒序排列,LINQ场景下替换为
OrderByDescending/ThenByDescending即可;IComparable场景下将最终返回的比较结果乘以-1即可。
内容的提问来源于stack exchange,提问作者Paul Johnson
相关产品推荐
相关产品推荐

