ICollection
Интерфейс ICollection определяется производным от IEnumerable; он дополняет этот интерфейс тремя свойствами, доступными только для чтения, и одним новым методом. Класс ICollection редко реализуется самостоятельно. Как правило, он образует базу для интерфейсов IList и IDictionary (см. ниже). Члены этого интерфейса перечислены
в табл. 5.2.
Таблица
5.2. Члены интерфейса ICollection
Метод/свойство |
Описание |
Count (свойство) | Возвращает количество элементов в коллекции |
IsSynchronized (свойство) | Используется в многопоточных приложениях (см. главу 12). Свойство возвращает True, если доступ к коллекции синхронизируется с учетом многопоточного доступа |
SyncRoot (свойство) | Также используется в многопоточных приложениях (см. главу 12). Свойство возвращает объект для синхронизации доступа к коллекции |
СоруТо (метод) | Копирует элементы из коллекции в массив, начиная с заданной позиции |
Интерфейс IList обеспечивает выборку элементов коллекции по индексу. Разумеется, поскольку этот интерфейс определяется производным от I Enumerable, при этом сохраняется возможность использования For-Each. Иерархия наследования IList выглядит следующим образом:
IEnumerable->ICollection->IList
Интерфейс IList относительно сложен — он состоит из трех свойств и семи методов (табл. 5.3). Напомним, что некоторые из методов могут быть пустыми, если в каком-то конкретном классе их реализация не имеет смысла.
Таблица
5.3. Члены интерфейса IList
Метод/свойство |
Описание |
IsFixedSize (свойство) | Логическое свойство. Показывает, имеет ли коллекция фиксированный размер |
IsReadOnly (свойство) | Логическое свойство. Показывает, доступна ли коллекция только для чтения |
Item (свойство) | Свойство доступно для чтения и записи. Используется для получения и присваивания значения объекта с заданным индексом |
Add (ByVal value As Object) As Integer (метод) | Включает объект в текущую позицию списка. Метод должен возвращать индекс, присвоенный добавленному элементу |
Clear (метод) | Удаляет все элементы из списка |
Contains (ByVal
value As Object) As Boolean (метод) |
Метод предназначен
для проверки наличия в списке заданного значения. Эффективная реализация
этого метода иногда бывает весьма нетривиальной задачей. Если элемент
присутствует в списке, метод возвращает True; в противном случае возвращается
False |
IndexOf (ByVal
value As Object) As Integer (метод) |
Возвращает индекс
заданного объекта в списке (программист также должен учитывать эффективность
реализации этого метода) |
Insert(ByVal
index As Integer, ByVal value As Object) (метод) |
Вставляет объект
в заданную позицию списка |
Remove(ByVal
value As Object) (метод) |
Удаляет первое
вхождение заданного объекта в списке |
Remove(ByVal
index As Integer) (метод) |
Удаляет элемент,
находящийся в заданной позиции |
Интерфейс IDictionary представляет коллекцию, в которой доступ к данным осуществляется по ключу — как в хэш-таблицах, описанных в предыдущей главе. Более того, класс хэш-таблиц в числе прочих реализует интерфейсы IDictionary, ICollection, Enumerable и ICloneable!
Хотя интерфейс IDictionary объявляется производным от Enumerable и переход к следующему элементу может осуществляться методом MoveNext, обычно такая возможность не используется — коллекции, реализующие IDictionary, ориентируются в первую очередь на обращение по ключу, а не на последовательный перебор элементов. По этой причине интерфейс IDictionary зависит от интерфейса IDic-tionaryEnumerator, который расширяет Enumerator и дополняет его тремя новыми свойствами:
- Entry: возвращает пару «ключ/значение» для текущего элемента словаря.
- Key: возвращает текущий ключ.
- Value: возвращает ссылку
на текущее значение.
Члены класса IDictionary перечислены в табл. 5.4.
Таблица
5.4. Члены интерфейса IDictionary
Метод/свойство |
Описание |
IsFixedSize
(свойство) |
Логическое свойство.
Показывает, имеет ли коллекция фиксированный размер |
IsReadOnly (свойство) |
Логическое свойство.
Показывает, доступна ли коллекция только для чтения |
Item (свойство) |
Свойство доступно
для чтения и записи. Используется для получения и присваивания значения
объекта с заданным индексом |
Keys (свойство) |
Возвращает объект,
реализующий интерфейс ICollection и содержащий все ключи ассоциативной
коллекции |
Values (свойство) |
Возвращает объект,
реализующий интерфейс ICollection и содержащий все значения ассоциативной
коллекции |
Add(ByVal key
As Object, ByVal value As Object) (метод) |
Добавляет объект
с заданным ключом (ключ должен быть уникальным) |
Clear (метод) |
Удаляет все
элементы из ассоциативной коллекции |
Contains (ByVal
key As Object) As Boolean (метод) |
Ищет значение
с заданным ключом |
GetEnumerator
(метод) |
Возвращает объект
IDictionaryEnumerator для работы с ключами и значениями |
Remove(ByVal
key As Object) (метод) |
Удаляет элемент
с заданным ключом |
Предположим, коллекцию объектов Employee потребовалось отсортировать по заработной плате. Конечно, операцию сортировки было бы удобно реализовать непосредственно в классе Emplоуее, чтобы сортировка простого или динамического массива объектов этого класса выполнялась так же просто, как сортировка строковых массивов. Оказывается, порядок сортировки элементов, используемый методом Sort классов Array и ArrayList, определяется интерфейсом IComparable (строковые массивы интерфейс IComparabl e сортирует в порядке ASCII-кодов). Интерфейс состоит из единственного метода CompareTo: Function CompareTo(ByValobj As Object) As Integer Метод возвращает следующие значения:
- отрицательное число, если текущий экземпляр меньше заданного объекта;
- ноль, если текущий экземпляр равен заданному объекту;
- положительное число,
если текущий экземпляр больше заданного объекта.
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
.NET Framework позволяет выполнять сортировку по нескольким критериям. Например, чтобы упорядочить массив работников сначала по заработной плате, а затем по имени (в группах с одинаковой зарплатой) следует реализовать интерфейс IComparer, содержащий единственный метод СотрагеТо. При этом вы сможете воспользоваться одной из перегруженных версий Array. Sort (или ArrayList. Sort), которая имеет следующую сигнатуру: Public Shared Sub Sort(ByVal array As Array. ByVal comparer As IComparer)
Обычно в программе создается отдельный класс, реализующий IComparer, и экземпляр этого класса передается методу Sort. Пример такого класса приведен ниже. Обратите внимание на выделенную строку — в ней имена работников передаются в виде строк методу Compare класса String:
Public Class SortByName
Implements IComparer
Public Function CompareTo(ByVal firstEmp As Object.ByVal
secondEmp=As Object) As Integer Implements IComparer.Compare Dim temp1 As Employee = CType(firstEmp,Employee) Dim temp2 As Employee = CType(secondEmp.Employee) Return String.Compare(templ.TheName. temp2.TheName) End Function End Class
Пример процедуры Sub Main с использованием этого класса:
SubMain()
Dim torn As New Employee("Tom", 50000)
Dim sally As New Employee("Sally". 60000)
Dim sam As New Employee("Sam". 60000)
Dim ted As New Employee("Ted". 50000)
Dim theEmployees() As Employee = _ {torn.sally,sam.ted}
Array.Sort(theEmployees)
Dim SortingByName As SortByName = New SortByName()
Array.Sort(theEmployees,SortingByName)
Dim aEmployee As Employee
For Each aEmployee In theEmployees
Console.WriteLine(aEmployee.TheName & "has yearly salary $" & FormatNumberCaEmployee.Salary))
Next
Console. ReadLine() End Sub .
Результат показан на рис. 5.10,
Рис.
5.10. Сортировка по нескольким критериям с использованием IComparer
Назад | Начало |