IComparable
Предположим, коллекцию объектов Employee потребовалось отсортировать по заработной плате. Конечно, операцию сортировки было бы удобно реализовать непосредственно в классе Emplоуее, чтобы сортировка простого или динамического массива объектов этого класса выполнялась так же просто, как сортировка строковых массивов. Оказывается, порядок сортировки элементов, используемый методом Sort классов Array и ArrayList, определяется интерфейсом IComparable (строковые массивы интерфейс IComparable сортирует в порядке ASCII-кодов). Интерфейс состоит из единственного метода CompareTo:
Function CompareTo(ByValobj As Object) As Integer
Метод возвращает следующие значения:
- отрицательное число, если текущий экземпляр меньше заданного объекта;
- ноль, если текущий экземпляр равен заданному объекту;
- положительное число, если текущий экземпляр больше заданного объекта.
Следующая версия класса Employee реализует интерфейсы lEnumerable и IComparable и сортирует массив по убыванию заработной платы:
Public Class Employee Implements IComparable Private m_Name As String Private m_Salary As Decimal Private Const LIMIT As Decimal =0.10 Public Sub New(ByVal theName As String,ByVal curSalary As Decimal) m_Name = theName m_Salary = curSalary End Sub Public Function CompareTo(ByVal anEmployee As Object) As Integer _ Implements IComparable.CompareTo If CType(anEmployee,Employee).Salany < Me.Salary Then Return – 1 El self CTypetanEmployee.Employee).Salary = Me.Salary Then Return 0 Elself CTypeCanEmployee,Employee).Salary > Me.Salary Then Return 1 End If End Function Public Readonly Property TheName() As String Get Return m_Name End Get End Property Public Readonly Property Salary() As Decimal Get Return MyClass.m_Salary End Get End Property Public Overridable Overloads Sub RaiseSalary(ByVal Percent As Decimal) If Percent > LIMIT Then ' Операция запрещена – необходим пароль Console.WriteLine("NEED PASSWORD TO RAISE SALARY MORE " & _ "THAN LIMIT!!!!") Else m_Salary =(1 + Percent) * m_Salary End If End Sub Public Overridable Overloads Sub RaiseSalary(ByVal Percent As Decimal._ ByVal Password As String) If Password = "special" Then m_Salary =(1 + Percent) * m_Salary End If End Sub End Class
Для тестирования новой версии класса можно воспользоваться следующей программой:
Sub Main() Dim torn As New Employee("Tom". 50000) Dim sally'As New Employee("Sally", 60000) Dim joe As New Employee("Joe", 20000) Dim gary As New Employее("Gary", 1) Dim theEmployees() As Employee = _ {torn, sally, joe .gary} Array.Sort(theEmployees) ' Порядок сортировки определяется CompareTo! Dim aEmployee As Employee For Each aEmployee In theEmployees Console.WriteLine(aEmployee.TheName & "has yearly salary $" & FormatNumbertaEmployee.Salary)) Next Console.ReadLine() End Sub
Результат показан на рис. 5.9.
Рис. 5.9. Сортировка по нестандартному критерию с использованием IComparable