Интерфейсы обобщенных коллекций



 

В пространстве имен System.Collections.Generic определен целый ряд интерфейсов обобщенных коллекций, имеющих соответствующие аналоги среди интерфейсов необобщенных коллекций. Все эти интерфейсы сведены в табл. 25.10.

 

Таблица 25.10. Интерфейсы обобщенных коллекций

 

Интерфейс - Описание

 

lCollection<T> - Определяет основополагающие свойства обобщенных коллекций

IComparer<T> Определяет обобщенный метод Compare() для сравнения объектов, хранящихся в коллекции lDictionary<Tkey, TValue> Определяет обобщенную коллекцию, состоящую из пар “ключ-значение"

IEnumerable<T> - Определяет обобщенный метод GetEnumerator(), предоставляющий перечислитель для любого класса коллекции

Enumerator<T> - Предоставляет методы, позволяющие получать содержимое коллекции по очереди

IEqualityComparer<T> -  Сравнивает два объекта на предмет равенства

IList<T> -  Определяет обобщенную коллекцию, доступ к которой можно получить с помощью индексатора

 

 

Интерфейс ICollection<T>

 

В интерфейсе ICollection<T> определен ряд свойств, которые являются общими для всех обобщенных коллекций. Интерфейс ICollection<T> является обобщенным вариантом необобщенного интерфейса ICollection, хотя между ними имеются некоторые отличия.

Итак, в интерфейсе ICollection<T> определены следующие свойства.

 

int Count { get; }

bool IsReadOnly { get; }

 

Свойство Count содержит ряд элементов, хранящихся в данный момент в коллекции. А свойство IsReadOnly имеет логическое значение true, если коллекция доступна только для чтения. Если же коллекция доступна как для чтения, так и для записи, то данное свойство имеет логическое значение false.

Кроме того, в интерфейсе ICollection<T> определены перечисленные ниже методы. Обратите внимание на то, что в этом обобщенном интерфейсе определено несколько большее количество методов, чем в его необобщенном аналоге.

 

Метод -  Описание

 

void Add(T item) -  Добавляет элемент item в вызывающую коллекцию. Генерирует исключение NotSupportedException, если коллекция доступна только для чтения

void Clear() -  Удаляет все элементы из вызывающей коллекции

bool Contains(T item) -  Возвращает логическое значение true, если вызывающая коллекция содержит элемент item , а иначе — логическое значение false

void CopyTo(T[] array, int arraylndex) -  Копирует содержимое вызывающей коллекции в массив array , начиная с элемента, указываемого по индексу arraylndex

void Remove(T item) -  Удаляет первое вхождение элемента item в вызывающей коллекции. Возвращает логическое значение true, если элемент i tem удален. А если этот элемент не найден в вызывающей коллекции, то возвращается логическое значение false

 

Некоторые из перечисленных выше методов генерируют исключение NotSupportedException, если коллекция доступна только для чтения.

А поскольку интерфейс ICollection<T> наследует от интерфейсов IEnumerable и IEnumerable<T>, то он включает в себя также обобщенную и необобщенную формы метода GetEnumerator().

Благодаря тому что в интерфейсе ICollection<T> реализуется интерфейс IEnumerable<T>, в нем поддерживаются также методы расширения, определенные в классе Enumerable. Несмотря на то что методы расширения предназначены главным образом для поддержки LINQ, им можно найти и другое применение, в том числе и в коллекциях.

 

 

Интерфейс IList<T>

 

В интерфейсе IList<T> определяется такое поведение обобщенной коллекции, которое позволяет осуществлять доступ к ее элементам по индексу с отсчетом от нуля. Этот интерфейс наследует от интерфейсов IEnumerable, IEnumerable<T> и ICollection<T> и поэтому является обобщенным вариантом необобщенного интерфейса IList. Методы, определенные в интерфейсе IList<T>, перечислены в табл. 25.11. В двух из этих методов предусматривается модификация коллекции. Если же коллекция доступна только для чтения или имеет фиксированный размер, то методы Insert() и RemoveAt() генерируют исключение NotSupportedException.

 

Таблица 25.11. Методы, определенные в интерфейсе IList<T>

 

Метод -  Описание

 

int IndexOf(Т item) -  Возвращает индекс первого вхождения элемента item в вызывающей коллекции. Если элемент item не обнаружен, то метод возвращает значение -1

void Insert(int index,  T item) -  Вставляет в вызывающую коллекцию элемент item по индексу index

void RemoveAt(int index) -  Удаляет из вызывающей коллекции элемент, расположенный по указанному индексу index

 

Кроме того, в интерфейсе IList<T> определяется индексатор

 

Т this[int index] { get; set; }

 

который устанавливает или возвращает значение элемента коллекции по указанному индексу index.

 

 

Интерфейс IDictionary<TKey, TValue>

 

В интерфейсе IDictionary<TKey, TValue> определяется такое поведение обобщенной коллекции, которое позволяет преобразовать уникальные ключи в соответствующие значения. Это означает, что в данном интерфейсе определяется коллекция, в которой хранятся пары "ключ-значение". Интерфейс IDictionary<TKey, TValue> наследует от интерфейсов IEnumerable, IEnumerable<KeyValuePair<TKey, TValue>> и ICollection<KeyValuePair<TKey, TValue>> и поэтому является обобщенным вариантом необобщенного интерфейса IDictionary. Методы, объявленные в интерфейсе IDictionary<TKey, TValue>, приведены в табл. 25.12. Все эти методы генерируют исключение ArgumentNullException при попытке указать пустой ключ.

 

Таблица 25.12. Методы, определенные в интерфейсе IDictionaryCTKey, TValue>

 

Метод - Описание

 

void Add(TKey key , TValue value) -  Добавляет в вызывающую коллекцию пару “ключ-значение”, определяемую параметрами key и value. Генерирует исключение ArgumentException, если ключ key уже находится в коллекции

bool Contains(TKey key) -  Возвращает логическое значение true, если вызывающая коллекция содержит элемент key в качестве ключа, а иначе — логическое значение false

bool Remove(TKey key) -  Удаляет из коллекции элемент, ключ которого равен значению key

bool TryGetValue(TKey key , out TValue value) -  Предпринимает попытку извлечь значение из коллекции по указанному ключу key и присвоить это значение переменной value. При удачном исходе операции возвращается логическое значение true, а иначе — логическое значение false. Если ключ key не найден, переменной value присваивается значение, выбираемое по умолчанию

 

Кроме того, в интерфейсе IDictionary<TKey, TValue> определены перечисленные ниже свойства.

 

Свойство - Описание

 

ICollection Keys<TKey> { get; } Подучает коллекцию ключей

ICollection Values<TValue> { get; } Получает коллекцию значений

 

Следует иметь в виду, что ключи и значения, содержащиеся в коллекции, доступны отдельными списками с помощью свойств Keys и Values.

И наконец, в интерфейсе IDictionary<TKey, TValue> определяется следующий индексатор.

 

TValue this[TKey key ] { get; set; }

 

Этот индексатор служит для получения и установки значения элемента коллекции, а также для добавления в коллекцию нового элемента. Следует, однако, иметь в виду, что в качестве индекса в данном случае служит ключ элемента, а не сам индекс.

 

 

Интерфейсы IEnumerable<T> и IEnumerator<T>

 

Интерфейсы IEnumerable<T> и IEnumerator<T> являются обобщенными эквивалентами рассмотренных ранее необобщенных интерфейсов IEnumerable и IEnumerator. В них объявляются аналогичные методы и свойства, да и действуют они по тому же принципу. Разумеется, обобщенные интерфейсы оперируют данными только того типа, который указывается в аргументе типа.

В интерфейсе IEnumerable<T> метод GetEnumerator() объявляется следующим образом.

 

IEnumerator<T> GetEnumerator()

 

Этот метод возвращает перечислитель типа Т для коллекции. А это означает, что он возвращает типизированный перечислитель.

Кроме того, в интерфейсе IEnumerable<T> определяются два таких же метода, как и в необобщенном его варианте: MoveNext() и Reset(). В этом интерфейсе объявляется также обобщенный вариант свойства Current.

 

Т Current { get; }

 

Это свойство возвращает ссылку типа Т на следующий объект. А это означает, что обобщенный вариант свойства Current является типизированным.

Но между интерфейсами IEnumerator и IEnumerator<T> имеется одно важное различие: интерфейс IEnumerator<T> наследует от интерфейса IDisposable, тогда как интерфейс IEnumerator не наследует от него. В интерфейсе IDisposable определяется метод Dispose(), который служит для освобождения неуправляемых ресурсов.

------------------------------------

ПРИМЕЧАНИЕ

В интерфейсе IEnumerable<T> реализуется также необобщенный интерфейс IEnumerable. Это означает, что в нем поддерживается необобщенный вариант метода GetEnumerator(). Кроме того, в интерфейсе IEnumerable<T> реализуется необобщенный интерфейс IEnumerator, а следовательно, в нем поддерживаются необобщенные варианты свойства Current.

------------------------------------

 

 

Интерфейс IComparer<T>

 

Интерфейс IComparer<Т> является обобщенным вариантом рассмотренного ранее интерфейса IComparer. Главное отличие между ними заключается в том, что интерфейс IComparer<T> обеспечивает типовую безопасность. В нем обобщенный вариант метода Compare() объявляется следующим образом.

 

Int Compare(Т х, Т у)

 

В этом методе сравниваются объекты х и у. Он возвращает положительное значение, если значение объекта х больше, чем у объекта у; отрицательное — если значение объекта х меньше, чем у объекта у; и нулевое значение — если сравниваемые значения равны.

 

 

Интерфейс IEqualityComparer<T>

 

Интерфейс IEqualityComparer<T> полностью соответствует своему необобщенному аналогу EqualityComparer. В нем определяются два следующих метода.

 

Bool Equals(Т х, Т у)

Int GetHashCode(Т obj)

 

Метод Equals() должен возвратить логическое значение true, если значения объектов х и у равны. А метод GetHashCode() возвращает хеш-код для объекта obj. Если два сравниваемых объекта равны, то их хеш-коды также должны быть одинаковы.

 

 

Интерфейс ISet<T>

 

Интерфейс ISet<T> был добавлен в версию 4.0 среды .NET Framework. Он определяет поведение обобщенной коллекции, реализующей ряд уникальных элементов. Этот интерфейс наследует от интерфейсов IEnumerable, IEnumerable<T>, а также ICollection<T>. В интерфейсе ISet<T> определен ряд методов, перечисленных в табл. 25.13. Обратите внимание на то, что параметры этих методов указываются как относящиеся к типу IEnumerable<T>. Это означает, что в качестве второго аргумента методу можно передать нечто, отличающееся от объектов типа ISet<T>. Но чаще всего оба аргумента оказываются экземплярами объектов типа ISet<T>.

 

Таблица 25.13. Методы, определенные в интерфейсе ISet<T>

 

Метод - Описание

 

void ExceptWith(Ienumerable<T> other) -   Удаляет из вызывающего множества те элементы, которые содержатся в другом множестве other  

void IntersectWith(IEnumerable<T> other) -   После вызова этого метода вызывающее множество содержит пересечение своих элементов с элементами другого множества other  

bool IsProperSubsetOf(IEnumerable<T> other) -   Возвращает логическое значение true, если вызывающее множество является правильным подмножеством другого множества other  , а иначе — логическое значение false

bool IsProperSupersetOf(lEnumerable<T> other) -   возвращает логическое значение true, если вызывающее множество является правильным надмножеством другого множества other, а иначе — логическое значение false

bool IsSubsetOf(IEnumerable<T> other) -   Возвращает логическое значение true, если вызывающее множество является подмножеством другого множества other  , а иначе — логическое значение false

bool IsSupersetOf(IEnumerable<T> other) -   Возвращает логическое значение true, если вызывающее множество является надмножеством другого множества other, а иначе — логическое значение false

bool Overlaps(IEnumerable<T> other) -   Возвращает логическое значение true, если вызывающее множество и другое множество other   содержат хотя бы один общий элемент, а иначе — логическое значение false

bool SetEquals(IEnumerable<T> other) -   Возвращает логическое значение true, если все   элементы вызывающего множества и другого множества other   оказываются общими, а иначе —логическое значение false. Порядок расположения элементов не имеет значения, а дублирующиеся элементы во другом множестве other   игнорируются

void SymmetricExceptWith (IEnumerable<T> other) -   После вызова этого метода вызывающее множество будет содержать симметрическую разность своих элементов и элементов другого множества other  

void UnionWith(IEnumerable<T> other) -   После вызова этого метода вызывающее множество будет содержать объединение своих элементов и элементов другого множества other  

 

 

Структура KeyValuePair<TKey, TValue>

 

В пространстве имен System.Collections.Generic определена структура KeyValuePair<TKey, TValue>. Она служит для хранения ключа и его значения и применяется в классах обобщенных коллекций, в которых хранятся пары "ключ-значение", как, например, в классе Dictionary<TKey, TValue>. В этой структуре определяются два следующих свойства.

 

public TKey Key { get; };

public TValue Value { get; };

 

В этих свойствах хранятся ключ и значение соответствующего элемента коллекции. Для построения объекта типа KeyValuePair<TKey, TValue> служит конструктор:

 

public KeyValuePair(TKey key, TValue value)  

 

где key обозначает ключ, a value — значение.

 

 

Классы обобщенных коллекций

 

Как упоминалось ранее, классы обобщенных коллекций по большей части соответствуют своим необобщенным аналогам, хотя в некоторых случаях они носят другие имена. Отличаются они также своей организацией и функциональными возможностями. Классы обобщенных коллекций определяются в пространстве имен System.Collections.Generic. В табл. 25.14 приведены классы, рассматриваемые в этой главе. Эти классы составляют основу обобщенных коллекций.

 

Таблица 25.14. Основные классы обобщенных коллекций

 

Класс -  Описание

 

Dictionary<Tkey, TValue> -  Сохраняет пары “ключ-значение". Обеспечивает такие же функциональные возможности, как и необобщенный класс Hashtable

HashSet<T> -  Сохраняет ряд уникальных значений, используя хеш-таблицу

LinkedList<T> -  Сохраняет элементы в двунаправленном списке

List<T> -  Создает динамический массив. Обеспечивает такие же функциональные возможности, как и необобщенный класс ArrayList

Queue<T> - Создает очередь. Обеспечивает такие же функциональные возможности, как и необобщенный класс Queue

SortedDictionary<TKey, TValue> -  Создает отсортированный список из пар “ключ-значение"

SortedList<TKey, TValue> -  Создает отсортированный список из пар “ключ-значение”. Обеспечивает такие же функциональные возможности, как и необобщенный класс SortedList

SortedSet<T> -  Создает отсортированное множество

Stack<T> -  Создает стек. Обеспечивает такие же функциональные возможности, как и необобщенный класс Stack

-------------------------------

ПРИМЕЧАНИЕ

В пространстве имен System.Collections.Generic находятся также следующие классы: класс SynchronizedCollection<T> синхронизированной коллекции на основе класса IList<T>; класс SynchronizedReadOnlyCollection<T>, доступной только для чтения синхронизированной коллекции на основе класса lList<T>; абстрактный класс SynchronizedKeyCollectionc<T> служащий в качестве базового для класса коллекции System.ServiceModel.UriSchemeKeyedCollection; а также класс KeyedByTypeCollection<T> коллекции, в которой в качестве ключей используются отдельные типы данных.

-------------------------------

 

 

Класс List<T>

 

В классе List<T> реализуется обобщенный динамический массив. Он ничем принципиально не отличается от класса необобщенной коллекции ArrayList. В этом классе реализуются интерфейсы ICollection, ICollection<T>, IList, IList<T>, IEnumerable и IEnumerable<T>. У класса List<T> имеются следующие конструкторы.

 

Public List()

public List(IEnumerable<T> collection)

Public List(int capacity)

 

Первый конструктор создает пустую коллекцию класса List с выбираемой по умолчанию первоначальной емкостью. Второй конструктор создает коллекцию типа List с количеством инициализируемых элементов, которое определяется параметром collection и равно первоначальной емкости массива. Третий конструктор создает коллекцию типа List, имеющую первоначальную емкость, задаваемую параметром capacity . В данном случае емкость обозначает размер базового массива, используемого для хранения элементов коллекции. Емкость коллекции, создаваемой в виде динамического массива, может увеличиваться автоматически по мере добавления в нее элементов.

В классе List<T> определяется ряд собственных методов, помимо тех, что уже объявлены в интерфейсах, которые в нем реализуются. Некоторые из наиболее часто используемых методов этого класса перечислены в табл. 25.15.

 

Таблица 25.15. Наиболее часто используемые методы, определенные в классе List<T>

 

Метод -  Описание

 

public virtual void AddRange(Icollection  collection) -  Добавляет элементы из коллекции collection в конец вызывающей коллекции типа ArrayList

public virtual int BinarySearch(T item) -  Выполняет поиск в вызывающей коллекции значения, задаваемого параметром item. Возвращает индекс совпавшего элемента. Если искомое значение не найдено, возвращается отрицательное значение. Вызывающий список должен быть отсортирован

public int BinarySearch(T  item,  IComparer<T> comparer) -  Выполняет поиск в вызывающей коллекции значения, задаваемого параметром item , используя для сравнения указанный способ, определяемый параметром comparer. Возвращает индекс совпавшего элемента. Если искомое значение не найдено, возвращается отрицательное значение. Вызывающий список должен быть отсортирован

public int BinarySearch(int  index,  int count, T item,  IComparer<T> comparer) -  Выполняет поиск в вызывающей коллекции значения, задаваемого параметром item , используя для сравнения указанный способ, определяемый параметром comparer. Поиск начинается с элемента, указываемого по индексу index, и включает количество элементов, определяемых параметром count. Метод возвращает индекс совпавшего элемента. Если искомое значение не найдено, возвращается отрицательное значение. Вызывающий список должен быть отсортирован

public List<T> GetRange(int  index,  int count) -  Возвращает часть вызывающей коллекции. Часть возвращаемой коллекции начинается с элемента, указываемого по индексу index , и включает количество элементов, задаваемое параметром count. Возвращаемый объект ссылается на те же элементы, что и вызывающий объект

public int IndexOf(T item) -  Возвращает индекс первого вхождения элемента item в вызывающей коллекции. Если искомый элемент не обнаружен, возвращается значение -1

public void InsertRange(int  index,  IEnumerable<T>  collection) -  Вставляет элементы коллекции collection в вызывающую коллекцию, начиная с элемента, указываемого по индексу index

public int LastlndexOf(T  item) -  Возвращает индекс последнего вхождения элемента item в вызывающей коллекции. Если искомый элемент не обнаружен, возвращается значение -1

public void RemoveRange(int  index,  int count) -  Удаляет часть вызывающей коллекции, начиная с элемента, указываемого по индексу index , и включая количество элементов, определяемое параметром count

public void Reverse() -  Располагает элементы вызывающей коллекции в обратном порядке

public void Reverse(int  index,  int count) -  Располагает в обратном порядке часть вызывающей коллекции, начиная с элемента, указываемого по индексу index , и включая количество элементов, определяемое параметром count

public void Sort() -  Сортирует вызывающую коллекцию по нарастающей

public void Sort(IComparer<T> comparer) -  Сортирует вызывающую коллекцию, используя для сравнения способ, задаваемый параметром comparer. Если параметр comparer имеет пустое значение, то для сравнения используется способ, выбираемый по умолчанию

public void Sort(Comparison<T> comparison) -  Сортирует вызывающую коллекцию, используя для сравнения указанный делегат

public void Sort(int index,  int count, IComparer<T>  comparer) -  Сортирует вызывающую коллекцию, используя для сравнения способ, задаваемый параметром comparer. Сортировка начинается с элемента, указываемого по индексу index , и включает количество элементов, определяемых параметром count. Если параметр comparer имеет пустое значение, то для сравнения используется способ, выбираемый по умолчанию

public T [ ] ToArray() -  Возвращает массив, содержащий копии элементов вызывающего объекта

public void TrimExcess() -  Сокращает емкость вызывающей коллекции таким образом, чтобы она не превышала 10% от количества элементов, хранящихся в ней на данный момент

 

В классе List<T> определяется также собственное свойство Capacity, помимо тех, что уже объявлены в интерфейсах, которые в нем реализуются. Это свойство объявляется следующим образом.

 

public int Capacity { get; set; }

 

Свойство Capacity позволяет установить и получить емкость вызывающей коллекции в качестве динамического массива. Эта емкость равна количеству элементов, которые может содержать коллекция до ее вынужденного расширения. Такая коллекция расширяется автоматически, и поэтому задавать ее емкость вручную необязательно. Но из соображений эффективности это иногда можно сделать, если заранее известно количество элементов коллекции. Благодаря этому исключаются издержки на выделение дополнительной памяти.

В классе List<T> реализуется также приведенный ниже индексатор, определенный в интерфейсе IList<T>.

 

public Т this[int index] { get; set; }

 

С помощью этого индексатора устанавливается и получается значение элемента коллекции, указываемое по индексу index.

В приведенном ниже примере программы демонстрируется применение класса List<T>. Это измененный вариант примера, демонстрировавшего ранее класс ArrayList. Единственное изменение, которое потребовалось для этого, заключалось в замене класса ArrayList классом List, а также в использовании параметров обобщенного типа.

 

// Продемонстрировать применение класса List<T>.

using System;

using System.Collections.Generic;

 

class GenListDemo {

static void Main() {


Дата добавления: 2019-02-12; просмотров: 303; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!