I have a class that has a collection of objects (a generic list). I'd like the user of my class to be able to supply a custom sort function, similar to the example code below. However, in my actual code, I'd like to keep the list of objects private, since the user doesn't really need access to them (except that it's the only successful way I've found so far to allow a user supplied sort function). I'd like to pass in the custom sort function as a property/method of my class or have a .Sort() method that accepts the custom function as input. My google searches have led me to 'delegates', which sound exactly like what I think I'm looking for, but I've not been able to translate their example code into working code for my situation.
Here's some working code but not quite what I want, as it gives public access to the list of objects.
Here's some working code but not quite what I want, as it gives public access to the list of objects.
Code:
Module Module1
Sub Main()
Dim theWidgetSorter As New widgetSorter
With theWidgetSorter.Widgets
.Add(New Widget("penny"))
.Add(New Widget("nickel"))
.Add(New Widget("dime"))
.Add(New Widget("quarter"))
End With
Console.WriteLine("original order:")
For Each tempWidget In theWidgetSorter.Widgets
Console.WriteLine(" " & tempWidget.Name)
Next
Console.WriteLine("")
theWidgetSorter.Widgets.Sort()
Console.WriteLine("alphabetical")
For Each tempWidget In theWidgetSorter.Widgets
Console.WriteLine(" " & tempWidget.Name)
Next
Console.WriteLine("")
theWidgetSorter.Widgets.Sort(AddressOf CompareNameLength)
Console.WriteLine("custom sort")
For Each tempWidget In theWidgetSorter.Widgets
Console.WriteLine(" " & tempWidget.Name)
Next
Console.WriteLine("")
Console.ReadLine()
End Sub
Public Function CompareNameLength(ByVal x As Widget, ByVal y As Widget) As Integer
If x.Name.Length > y.Name.Length Then
Return 1
End If
If x.Name.Length < y.Name.Length Then
Return -1
End If
If x.Name.Length = y.Name.Length Then
Return 0
End If
End Function
End Module
Class Widget
Implements IComparable(Of Widget)
Private _name As String
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
Public Sub New(ByVal widgetName As String)
Me.Name = widgetName
End Sub
Public Function CompareTo(other As Widget) As Integer Implements System.IComparable(Of Widget).CompareTo
' A null value means that this object is greater.
If other Is Nothing Then
Return 1
Else
Return Me.Name.CompareTo(other.Name)
End If
End Function
End Class
Class widgetSorter
Private _widgetList As New List(Of Widget)
Public Property Widgets() As List(Of Widget)
Get
Return _widgetList
End Get
Set(ByVal value As List(Of Widget))
_widgetList = value
End Set
End Property
Public Delegate Function CustomSort(ByVal x As Widget, ByVal y As Widget) As Integer
Private myCustomSort As CustomSort
Public Property CustomSortDelegate() As CustomSort
Get
Return myCustomSort
End Get
Set(ByVal value As CustomSort)
myCustomSort = value
End Set
End Property
Public Sub SortWidgets()
If IsNothing(myCustomSort) Then
'sort alphabetically
_widgetList.Sort()
Else
'use custom sort function
_widgetList.Sort(myCustomSort)
End If
End Sub
End Class