Практический пример: специализированная сортировка
Предыдущие примеры выглядят искусственно и относятся к категории "игрушечных программ". В этом разделе мы покажем, как использовать делегаты при специализированной сортировке – одной из стандартных областей применения функций обратного вызова. Общая идея заключается в том, что один метод сортировки в зависимости от ситуации может использовать разные критерии сортировки. Предположим, у вас имеется массив имен: "Mike Item", "Dave Mendlen", "Alan Carter", "Tony Goodhew", "Ari Bixhorn", "Susan Warren".
Если вызвать метод Sort класса Array, сортировка будет произведена по именам. А если вы хотите отсортировать массив по фамилиям?
Примечание
Возможный подход к решению этой задачи описан в главе 5 – вы можете написать собственную реализацию интерфейса IComparer и передать ее Sort. Применение обратного вызова на базе делегатов выглядит чуть более элегантно и теоретически обладает большей гибкостью, поскольку программист может определить собственные процедуры сортировки, которые в конкретной ситуации работают эффективнее стандартных алгоритмов.
Чтобы массив поддерживал сортировку по именам, следует определить класс с несколькими методами Compare и при помощи делегата связать алгоритм сортировки с нужным методом Compare через механизм обратного вызова. В частности, это позволит динамически изменять критерий сортировки во время работы программы.
Прежде всего определяется класс, выполняющий сортировку. Чтобы избежать подробного обсуждения различных алгоритмов сортировки, мы воспользуемся простейшим алгоритмом волновой сортировки:
- Начать с первого элемента.
- Последовательно просмотреть все остальные элементы. Если очередной элемент окажется меньше текущего первого элемента, поменять их местами.
- Начать со второго элемента, просмотреть все остальные элементы.
- Продолжать до последнего элемента.
Основной код волновой сортировки выглядит так:
For i =bottom To (top -bottom) For j =i + 1 To top If Stuff(j) < Stuff(i))Then temp = Stuff(i) Stuff(i) = Stuff(j) Stuff(j) = temp End If Next j Next I
Чтобы реализовать этот алгоритм с применением функций обратного вызова, необходимо определить класс Special Sort с делегатом, используемым при обратном вызове. Код этого класса приведен ниже:
1 Public Class Special Sort 2 ' Определение делегата 3 Public Delegate Function SpecialCompareCallback(ByVal flrstString _ As String,ByVal secondString As String) As Boolean 4 ' Определение процедуры, вызываемой делегатом 5 Public Shared Sub IfySort(ByVal Stuff As String()._ByVal MyCompare As SpecialCompareCallback) 6 Dim i, j As Integer 7 Dim temp As String 8 Dim bottom As Integer = Stuff.GetLowerBound(0) 9 Dim top As Integer = Stuff.GetUpperBound(0) 10 For i = bottom To (top = bottom) 11 For j = i + 1 To top 12 If MyCompare(Stuff(j). Stuff(i)) Then 13 temp = Stuff(i) 14 Stuff(1) -Stuff (j) 15 Stuff(j) = temp 16 End If 17 Next j 18 Next i 19 End Sub 20 End Class