Visual Basic 9 (2008)Visual Basic 8 (2005).NET 3.0Visual Studio 2005设计/图形.NET 2.0C# 2.0初学者C# 3.0开发Visual Studio.NETVisual BasicASP.NETC#
排序通用集合





4.00/5 (7投票s)
本文介绍了如何对通用集合进行排序
引言
在本文中,我将讨论如何使用反射来排序泛型集合。如果使用代码中不存在的类型,则需要修改此代码。此外,如果您想基于类型不是基本类型(整数、字符串等)的变量进行排序,则需要修改代码。此代码只是为您提供排序集合的基本理解,但您需要对其进行修改以满足您的需求。
背景
.NET 2.0 的一大优势是集合和泛型。现在我们可以将对象列表绑定到网格、下拉列表等。在数据集世界中,我们可以使用 DataTable 或 DataView 的 sort 方法来排序结果。集合也提供了相同的选项。本文将讨论如何进行泛型集合排序。
使用代码
以下代码显示了泛型集合排序器
Imports System.Reflection
Namespace CollectionSorter
Public Class CollectionSorter(Of T)
Implements IComparer(Of T)
#Region "Private Variables"
Private _sortColumn As String
Private _reverse As Boolean
#End Region
#Region "Constructor"
Public Sub New(ByVal sortEx As String)
'find if we want to sort asc or desc
If Not String.IsNullOrEmpty(sortEx) Then
_reverse = sortEx.ToLowerInvariant().EndsWith(" desc")
If _reverse Then
_sortColumn = sortEx.Substring(0, sortEx.Length - 5)
Else
If sortEx.ToLowerInvariant().EndsWith(" asc") Then
_sortColumn = sortEx.Substring(0, sortEx.Length - 4)
Else
_sortColumn = sortEx
End If
End If
End If
End Sub
#End Region
#Region "Interface Implementation"
Public Function Compare(ByVal x As T,
ByVal y As T) As Integer Implements System.Collections.Generic.IComparer(
Of T).Compare
'get the properties of the objects
Dim propsx() As PropertyInfo = x.GetType().GetProperties(
System.Reflection.BindingFlags.Instance Or System.Reflection.BindingFlags.Public)
Dim propsy() As PropertyInfo = x.GetType().GetProperties(
System.Reflection.BindingFlags.Instance Or System.Reflection.BindingFlags.Public)
Dim retval As Integer
'find the column we want to sort based on
For i As Integer = 0 To propsx.Length - 1
If _sortColumn.ToLower() = propsx(i).Name.ToLower() Then
'find the type of column so we know how to sort
Select Case propsx(i).PropertyType.Name
Case "String"
retval = CStr(propsx(i).GetValue(x, Nothing)).CompareTo(
CStr(propsy(i).GetValue(y, Nothing)))
Case "Integer"
retval = CInt(propsx(i).GetValue(x, Nothing)).CompareTo(
CInt(propsy(i).GetValue(y, Nothing)))
Case "Int32"
retval = CInt(propsx(i).GetValue(x, Nothing)).CompareTo(
CInt(propsy(i).GetValue(y, Nothing)))
Case "Int16"
retval = CInt(propsx(i).GetValue(x, Nothing)).CompareTo(
CInt(propsy(i).GetValue(y, Nothing)))
Case "DateTime"
retval = CDate(propsx(i).GetValue(x, Nothing)).CompareTo(
CDate(propsy(i).GetValue(y, Nothing)))
End Select
End If
Next
If _reverse Then
Return -1 * retval
Else
Return retval
End If
End Function
#End Region
#Region "Equal Function"
Public Function Equals(ByVal x As T, ByVal y As T) As Boolean
Dim propsx() As PropertyInfo = x.GetType().GetProperties(
System.Reflection.BindingFlags.Instance Or System.Reflection.BindingFlags.Public)
Dim propsy() As PropertyInfo = y.GetType().GetProperties(
System.Reflection.BindingFlags.Instance Or System.Reflection.BindingFlags.Public)
Dim retval As Boolean
For i As Integer = 0 To propsx.Length - 1
If _sortColumn.ToLower() = propsx(i).Name.ToLower() Then
retval = propsx(i).GetValue(x, Nothing).Equals(propsy(i).GetValue(y,
Nothing))
End If
Next
Return retval
End Function
#End Region
End Class
End Namespace
首先,该类应继承自 IComparer(Of T)
接口。此接口只有一个方法。需要实现的方法是Public Function Compare(ByVal x As T, ByVal y As T) As Integer
基本上,此方法比较两个类型为T
的对象。让我们退一步,在类的构造函数中,我们将获得排序表达式,例如,如果我们有一个名为“Title”的属性的对象 book,并且想基于标题进行排序,我们应该使用类似于“Title asc”或“Title desc”的表达式。在 compare
函数中,我们将使用反射器找到要排序的列,然后我使用反射器获取列的类型,然后我使用该类型的 compare 方法来比较值。
我实现的另一个函数是 Equal
。
以下代码显示了如何使用泛型集合排序器
Dim BookList As List(Of Book) = New List(Of Book)
Dim m_book As Book
m_book = New Book()
m_book.Author = "Bill Gates"
m_book.Title = "How to get rich as software engineer!"
m_book.PublishDate = "1/1/2000"
BookList.Add(m_book)
m_book = New Book()
m_book.Author = "Steve Job"
m_book.Title = "Why apple went down the drain!"
m_book.PublishDate = "1/1/2007"
BookList.Add(m_book)
Dim colsorter As CollectionSorter(Of Book) = New CollectionSorter(Of Book)(
"Author asc")
BookList.Sort(colsorter)
关注点
为了改进此代码,您可以让用户能够基于多个列(属性)进行排序。