Страница 443 из 502
И последнее замечание: если у вас имеется некоторый опыт программирования на C++, то вам, вероятно, будет полезно знать, что классы коллекций по своей сути подобны классам стандартной библиотеки шаблонов (Standard Template Library — STL), определенной в C++. То, что в программировании на C++ называется контейнером, в программировании на C# называется коллекцией. Это же относится и к Java. Если вы знакомы с библиотекой Collections Framework для Java, то научиться пользоваться коллекциями в C# не составит для вас большого труда.
В силу характерных отличий каждый из пяти типов коллекций (необобщенных, обобщенных, специальных, с поразрядной организацией и параллельных) будет рассмотрен далее в этой главе отдельно.
Необобщенные коллекции
Необобщенные коллекции вошли в состав среды .NET Framework еще в версии 1.0. Они определяются в пространстве имен System.Collections. Необобщенные коллекции представляют собой структуры данных общего назначения, оперирующие ссылками на объекты. Таким образом, они позволяют манипулировать объектом любого типа, хотя и не типизированным способом. В этом состоит их преимущество и в то же время недостаток. Благодаря тому что необобщенные коллекции оперирухрт ссылками на объекты, в них можно хранить разнотипные данные. Это удобно в тех случаях, когда требуется манипулировать совокупностью разнотипных объектов или же когда типы хранящихся в коллекции объектов заранее неизвестны. Но если коллекция предназначается для хранения объекта конкретного типа, то необобщенные коллекции не обеспечивают типовую безопасность, которую можно обнаружить в обобщенных коллекциях.
Необобщенные коллекции определены в ряде интерфейсов и классов, реализующих эти интерфейсы. Все они рассматриваются далее по порядку.
Интерфейсы необобщенных коллекций
В пространстве имен System.Collections определен целый ряд интерфейсов необобщенных коллекций. Начинать рассмотрение необобщенных коллекций следует именно с интерфейсов, поскольку они определяют функциональные возможности, которые являются общими для всех классов необобщенных коллекций. Интерфейсы, служащие опорой для необобщенных коллекций, сведены в табл. 25.1. Каждый из этих интерфейсов подробно описывается далее.
Таблица 25.1. Интерфейсы необобщенных коллекций
Интерфейс - Описание
ICollection - Определяет элементы, которые должны иметь все необобщенные коллекции
IComparer - Определяет метод Compare() для сравнения объектов, хранящихся в коллекции
IDictionary - Определяет коллекцию, состоящую из пар “ключ-значение”
IDictionaryEnumerator - Определяет перечислитель для коллекции, реализующей интерфейс IDictionary
IEnumerable - Определяет метод GetEnumerator(), предоставляющий перечислитель для любого класса коллекции
IEnumerator - Предоставляет методы, позволяющие получать содержимое коллекции по очереди
IEqualityComparer - Сравнивает два объекта на предмет равенства
IHashCodeProvider - Считается устаревшим. Вместо него следует использовать интерфейс IEqualityComparer
IList - Определяет коллекцию, доступ к которой можно получить с помощью индексатора
IStructuralComparable - Определяет метод CompareTo(), применяемый для структурного сравнения
IStructuralEquatable - Определяет метод Equals(), применяемый для выяснения структурного, а не ссылочного равенства. Кроме того, определяет метод GetHashCode()
Интерфейс ICollection служит основанием, на котором построены все необобщенные коллекции. В нем объявляются основные методы и свойства для всех необобщенных коллекций. Он также наследует от интерфейса IEnumerable.
В интерфейсе ICollection определяются перечисленные ниже свойства. Свойство Count используется чаще всего, поскольку оно содержит количество элементов, хранящихся в коллекции на данный момент. Если значение свойства Count равно нулю, то коллекция считается пустой.
В интерфейсе ICollection определяется следующий метод.
<b>void CopyTo(Array target, int startldx)</b>
Свойство - Назначение
int Count { get; } - Содержит количество элементов в коллекции на данный момент
bool isSynchronized { get; } - Принимает .логическое значение true, если коллекция синхронизирована, а иначе — логическое значение false. По умолчанию коллекции не синхронизированы. Но для большинства коллекций можно получить синхронизированный вариант
object SyncRoot { get; } - Содержит объект, для которого коллекция может быть синхронизирована
Метод CopyTo() копирует содержимое коллекции в массив target, начиная с элемента, указываемого по индексу startldx. Следовательно, метод CopyTo() обеспечивает в C# переход от коллекции к стандартному массиву.
Благодаря тому что интерфейс ICollection наследует от интерфейса IEnumerable, в его состав входит также единственный метод, определенный в интерфейсе IEnumerable. Это метод GetEnumerator(), объявляемый следующим образом.
<b>IEnumerator GetEnumerator()</b>
Он возвращает перечислитель для коллекции.
Вследствие того же наследования от интерфейса IEnumerable в интерфейсе ICollection определяются также четыре следующих метода расширения: AsParallel(), AsQueryable(), Cast() и OfType(). В частности, метод AsParallel() объявляется в классе System.Linq.ParallelEnumerable, метод AsQueryable() — в классе System.Linq.Queryable, а методы Cast() и OfType() — в классе System.Linq.Enumerable. Эти методы предназначены главным образом для поддержки LINQ, хотя их можно применять и в других целях.
В интерфейсе IList объявляется такое поведение необобщенной коллекции, которое позволяет осуществлять доступ к ее элементам по индексу с отсчетом от нуля. Этот интерфейс наследует от интерфейсов ICollection и IEnumerable. Помимо методов, определенных в этих интерфейсах, в интерфейсе IList определяется ряд собственных методов. Все эти методы сведены в табл. 25.2. В некоторых из них предусматривается модификация коллекции. Если же коллекция доступна только для чтения или имеет фиксированный размер, то в этих методах генерируется исключение NotSupportedException.