Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lab8.doc
Скачиваний:
14
Добавлен:
21.09.2019
Размер:
418.82 Кб
Скачать

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

В пространстве имен System.Collections определены наборы стандартных коллекций и интерфейсов, которые реализованы в этих коллекциях. В таблице 8.1 приведены наиболее важные интерфейсы, часть из которых мы уже изучали в разделе «Стандартные интерфейсы .NET.

Таблица 8.1. Интерфейсы пространства имен System.Collections

Интерфейс

Назначение

ICollection

Определяет общие характеристики (например, размер) для набора элементов

IComparer

Позволяет сравнивать два объекта

IDictionary

Позволяет представлять содержимое объекта в виде пар «имя-значение»

IDictionaryEnumerator

Используется для нумерации содержимого объекта, поддерживающего интерфейс IDictionary

IEnumerable

Возвращает интерфейс IEnumerator для указанного объекта

IEnumerator

Обычно используется для поддержки оператора foreach в отношении объектов

IHashCodeProvider

Возвращает хеш-код для реализации типа с применением выбранного пользователем алгоритма хеширования

IList

Поддерживает методы добавления, удаления и индексирования элементов в списке объектов

В таблице 8.2 перечислены основные коллекции, определенные в пространстве System.Collections.

Таблица 8.2. Коллекции пространства имен System.Collections

Класс

Назначение

Важнейшие из реализованных интерфейсов

ArrayList

Массив, динамически изменяющий свой размер

IList, ICollection, IEnumerable, ICloneable

BitArray

Компактный массив для хранения битовых значений

ICollection, IEnumerable, ICloneable

Hashtable

Хеш-таблица

IDictionary, ICollection, IEnumerable, ICloneable

Queue

Очередь

ICollection, ICloneable, IEnumerable

SortedList

Коллекция, отсортированная по ключам. Доступ к элементам — по ключу или по индексу

IDictionary, ICollection, IEnumerable, ICloneable

Stack

Стек

ICollection, IEnumerable

Пространство имен System.Collections.Specialized включает специализированные коллекции, например, коллекцию строк StringCollection и хеш-таблицу со строковыми ключами StringDictionary.

В качестве примера стандартной коллекции рассмотрим класс ArrayList.

Класс ArrayList

Основным недостатком обычных массивов является то, что объем памяти, необходимый для хранения их элементов, должен быть выделен до начала работы с массивом. Класс ArrayList позволяет программисту не заботиться о выделении памяти и хранить в одном и том же массиве элементы различных типов.

По умолчанию при создании объекта типа ArrayList строится массив из 16 элементов типа object. Можно задать желаемое количество элементов в массиве, передав его в конструктор или установив в качестве значения свойства Capacity, например:

ArrayList arr1 = new ArrayList(); // создается массив из 16 элементов

ArrayList arr2 = new ArrayList(1000); // создается массив из 1000 элементов

ArrayList arr3 = new ArrayList();

arr3.Capacity = 1000; // количество элементов задается

Основные методы и свойства класса ArrayList перечислены в таблице 8.3.

Таблица 8.3. Основные элементы класса ArrayList

Элемент

Вид

Описание

Capacity

Свойство

Емкость массива (количество элементов, которые могут храниться в массиве)

Count

Свойство

Фактическое количество элементов массива

Item

Свойство

Получить или установить значение элемента по заданному индексу

Add

Метод

Добавление элемента в конец массива

AddRange

Метод

Добавление серии элементов в конец массива

BinarySearch

Метод

Двоичный поиск в отсортированном массиве или его части

Clear

Метод

Удаление всех элементов из массива

Clone

Метод

Поверхностное копирование элементов одного массива в другой массив

CopyTo

Метод

Копирование всех или части элементов массива в одномерный массив

GetRange

Метод

Получение значений подмножества элементов массива в виде объекта типа ArrayList

IndexOf

Метод

Поиск первого вхождения элемента в массив (возвращает индекс найденного элемента или –1, если элемент не найден)

Insert

Метод

Вставка элемента в заданную позицию (по заданному индексу)

InsertRange

Метод

Вставка группы элементов, начиная с заданной позиции

LastIndexOf

Метод

Поиск последнего вхождения элемента в одномерный массив

Remove

Метод

Удаление первого вхождения заданного элемента в массив

RemoveAt

Метод

Удаление элемента из массива по заданному индексу

RemoveRange

Метод

Удаление группы элементов из массива

Reverse

Метод

Изменение порядка следования элементов на обратный

SetRange

Метод

Установка значений элементов массива в заданном диапазоне

Sort

Метод

Упорядочивание элементов массива или его части

TrimToSize

Метод

Установка емкости массива, равной фактическому количеству элементов

Класс ArrayList реализован через класс Array, то есть содержит закрытое поле этого класса. Поскольку все типы в C# являются потомками класса object, массив может содержать элементы произвольного типа. Даже если в массиве хранятся обычные целые числа, то есть элементы значимого типа, внутренний класс является массивом ссылок на экземпляры типа object, которые представляют собой упакованный тип-значение. Соответственно, при занесении в массив выполняется упаковка, а при извлечении – распаковка элемента. Это не может не сказаться на быстродействии алгоритмов, использующих ArrayList.

Если при добавлении элемента в массив оказывается, что фактическое количество элементов массива превышает его емкость, она автоматически удваивается, то есть происходит повторное выделение памяти и переписывание туда всех существующих элементов.

Пример занесения элементов в экземпляр класса ArrayList:

arr1.Add( 123 );

arr1.Add( -2 );

arr1.Add( "Вася" );

Доступ к элементу выполняется по индексу, однако при этом необходимо явным образом привести полученную ссылку к целевому типу, например:

int a = (int) arr1[0];

int b = (int) arr1[1];

string s = (string) arr1[2];

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

Для повышения надежности программ применяется следующий прием: экземпляр класса ArrayList объявляется закрытым полем класса, в котором необходимо хранить коллекцию значений определенного типа, а затем описываются методы работы с этой коллекцией, делегирующие свои функции методам ArrayList. Этот способ иллюстрируется в листинге 8.8, где создается класс для хранения объектов типа Monster и производных от него. По сравнению с аналогичным листингом из раздела «Виртуальные методы», в котором используется обычный массив, у нас появилась возможность хранить в классе Stado произвольное количество элементов.

Листинг 8.8. – Коллекция объектов

using System;

using System.Collections;

namespace ConsoleApplication1

{

class Monster { ... }

class Daemon : Monster { ... }

class Stado : IEnumerable

{

private ArrayList list;

public Stado() { list = new ArrayList(); }

public void Add( Monster m ) { list.Add( m ) ; }

public void RemoveAt( int i ) { list.RemoveAt( i ); }

public void Clear() { list.Clear(); }

public IEnumerator GetEnumerator()

{ return list.GetEnumerator(); }

}

class Class1

{ static void Main()

{

Stado stado = new Stado();

stado.Add( new Monster( "Monia" ) );

stado.Add( new Monster( "Monk" ) );

stado.Add( new Daemon ( "Dimon", 3 ) );

stado.RemoveAt( 1 );

foreach ( Monster x in stado ) x.Passport();

}

}

}

Результат работы программы:

Monster Monia health = 100 ammo = 100

Daemon Dimon health = 100 ammo = 100 brain = 3

Недостатком этого решения является то, что для каждого метода стандартной коллекции приходится описывать метод-оболочку, вызывающий стандартный метод. Хотя это и несложно, но несколько неизящно. В C#, начиная с версии 2.0, появились классы-прототипы (generics), позволяющие решить эту проблему. Мы рассмотрим их в следующем разделе.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]