Пространство имен System.Collections

advertisement
Коллекции
Пространство имен
System.Collections
Наиболее простой вариант набора элементов — это массив
System. Array . Он уже обладает весьма полезными
встроенными функциями, которые позволяют производить
операции сортировки, клонирования, перечисления и
расстановки элементов в обратном порядке. Однако создатели
библиотеки базовых классов С# приготовили для нас большое
количества встроенных типов, которые позволят сэкономить
массу времени при решении часто встречающихся задач. Все
эти типы, как следует из самого названия System.Collections,
предназначены для работы с наборами элементов.
Первое, о чем необходимо сказать, это то что — в
System.Collections определен набор стандартных интерфейсов.
Кроме того, эти же интерфейсы определены в большинстве
классов System.Collections . Краткий перечень наиболее важных
интерфейсов пространства имен System.ColIections представлен в
таблице.
Но сначала поговорим об «отношениях» этих интерфейсов.
Многие интерфейсы объединены в иерархии, когда как некоторые
существуют отдельно и независимо от остальных. Отношения
наследования представлены на рисунке.
Схема отношений наследования
Теперь приведем краткий перечень интерфейсов…
Интерфейсы пространства имен System.Collections
Интерфейс
Назначение
ICollection
Определяет общие характеристики (например,
только для чтения и т. д.)
для класса-набора элементов
IComparer
Позволяет сравнивать два объекта
IDictionary
Позволяет представлять содержимое объекта в
виде пар имя — значение
IList
Обеспечивает методы для добавления,
удаления и индексирования элементов в списке
объектов
Интерфейсы пространства имен System.Collections
Интерфейс
Назначение
IDictionary
Enumerator
Используется для нумерации содержимого объекта,
поддерживающего IDictionary
lEnumerable
Возвращает интерфейс lEnumerator для указанного
объекта
lEnumerator
Обычно используется для поддержки конструкции
foreach в отношении
объектов
IHashCodeProvider
Возвращает хэш-код для реализации типа с
применением выбранного
пользователем алгоритма хэширования
Теперь представим наиболее используемые классы…
Классы System.Collections
Класс
Назначение
Важнейшие из
реализованных
интерфейсов
ArrayList
Динамически изменяющий
свой размер массив объектов
IList, ICollection,
lEnumerable
Hashtable
Представляет набор
взаимосвязанных ключей
и значений, основанных
на хэш-коде ключа.
IDictionary, ICollection,
lEnumerable
и ICIoneable. Кроме того, у
типов,
которые предназначены для
хранения в Hashtable, всегда
должен быть замещен метод
System, ObjectGetHashCodeQ
Queue
Стандартная очередь,
реализованная по принципу
FIFO (first-in-first-out,
«первым
ICollection, ICIoneable
и lEnumerable
Классы System.Collections
Класс
Назначение
Важнейшие из
реализованных
интерфейсов
Sorted List
Аналогично словарю, однако
к элементам можно также
обратиться по их порядковому
номеру(индексу)
IDictiOtiary, ICollection,
lEnumerable
и ICIoneable
Stack
Очередь, реализованная
по принципу UFO
(last-in-first-out, «последним
пришел, первым ушел»),
обеспечивающая возможности
по проталкиванию данных
в стек, выталкиванию данных
из стека и считыванию данных
ICollection и
lEnumerable
Пространство имен System.Collections.Specialized
Если ни один из классов, представленных в пространстве имен
System.Collection, вам не подходит, есть смысл заглянуть в
пространство имен System.Collections.Specialized. В этом
пространстве имен определен свой набор типов для работы с
наборами элементов. Как видно из названия пространства имен,
эти типы предназначены для
специальных случаев. В качестве примера можно назвать типы
StringDIctionary и ListDictionary, которые специальным образом
реализуют интерфейс IDictionary.
Применение ArrayList
При ближайшем рассмотрении классов, определенных в
пространстве имен System.Collections, выясняется, что они
обладают очень схожей функциональностью и реализуют одни и те
же интерфейсы. Поэтому вместо того, чтобы углубляться в
подробности реализации каждого из классов, мы подробно
разберем применение лишь одного из них —
System.Collections.ArrayList,
Для того чтобы воспользоваться возможностями ArrayList, мы
применим не классическое наследование, а модель включения делегирования, когда класс ArrayList будет вложен внутрь
созданного ранее класса Cars). Фактически единственное, что мы
должны сделать, — реализовать в Cars набор открытых методов,
которые будут передавать вызовы на выполнение различных
действий (делегировать) внутреннему классу carList, производному
от ArrayList.
Выглядеть всё это будет так:
//Нам больше не нужно реализовывать lEnumerator - все уже сделано за
нас в ArrayList
public class Cars: IEnumerable
{
// Это - тот самый внутренний класс, который и будет делать всю работу
private ArrayList carList:
// Создаем объект класса carList при помощи конструктора Cars
public Cars() {carLlst = new ArrayLis():}
// Реализуем нужные нам методы для приема вызовов извне и передачи их carList
// Метод для вставки объекта Саг
public void AddCar(Car с)
{ carList.Add(c); }
// Метод для удаления объекта Саг
public void RemoveCar(int carToRemove)
{ carList.RernoveAt(carToRemove); }
// Свойство, возвращающее количество объектов Car
public int CarCount
{ get { return carList.Count; } }
// Метод для очистки объекта - удаления всех объектов Саг
public void ClearAllCarsO
{ carList.Clear(); }
// Метод. который отвечает на вопрос - есть ли уже в наборе такой объект Саг
public bool CarlsPresent(Car с)
{ return carList.Contains(c); }
// А все, что связано с реализацией lEnumerator, мы просто перенаправляем в carList
public lEnumerator GetEnumerator()
{ return carList.GetEnumerator(); }
}
А теперь покажем, что такое объявление проще использовать…
public static void Main()
{
Cars carLot = new Cars();
// Чтобы было с чем работать, добавляем несколько объектов Саг
carLot.AddCar( new Саг("Jasper", 200. 80));
carLot.AddCar( new Car("Mandy, 140. 80));
carLot.AddCar( new CarCPorker". 90, 90));
carLot.AddCar( new CarC'Jimbo", 40, 4));
// Выводим информацию о каждом классе при помощи конструкции foreach
Console.WriteLine('You have {0} in the lot; \n". carLot.CarCount);
foreach (Саг с in carLot)
{
Console.WriteLine('Name: {0}', c.PetName):
Console.WriteLine('Max speed; {0}\n". c.MaxSpeed);
}
// Удаляем одну из машин
carLot.RemoveCar():
Console.WriteLine('You have {0} in the lot.Xn“, carLot.Car-Count):
// Добавляем еще одну машину и проверяем ее наличие в наборе
Саг temp = new Car("Zippy", 90. 90);
CarLot.AddCar(temp);
If(carLot.CarlsPresent(temp))
Console.WriteLine(ternp.PetName + " is already in the lot.");
car-Lot.ClearAllCar():
Console.WriteLine('You have {0} In the 1ot.\n", carLot.Car-Count"};
}
Результат
В результате работы программы мы получим:
Вместо заключения…
Теперь настало время ответить на вопрос — а почему нельзя
просто произвести класс Cars от ArrayList? Зачем потребовалось
все усложнять и создавать внутри Cars вспомогательный класс и
дополнительные методы? Ответ очень прост — ArrayList сам по
себе работает с любыми объектами. Это значит, что при
использовании классического наследования класс Cars можно
было бы заполнить объектами абсолютно любых типов С#.
Download