Интерфейсы коллекций
lEnumerable и JEnumerator
Исходным для всех интерфейсов, предназначенных для работы с коллекциями, является интерфейс lEnumerable, имеющий один метод – GetEnumerator.
_gc _interface lEnumerable // сборщик мусора – lEnumerable { lEnumerator* GetEnumerator(); };
GetEnumerator возвращает указатель на интерфейс lEnumerator, который используется для последовательного доступа к элементам коллекции. Этот интерфейс имеет свойство Current (Текущая запись) и методы MoveNext и Reset (Сброс).
_gc _interface lEnumerator // сборщик мусора – lEnumerator { _property Object* get__Current (); bool MoveNext(); // логический (булев) void Reset(); };
Сразу после инициализации нумератор указывает на позицию перед первым элементом коллекции и, следовательно, для получения доступа даже к первому ее элементу его следует продвинуть. Использование нумератора для последовательного доступа к элементам списка проиллюстрировано в методе ShowEnum.
static void ShowEnum(ArrayList *pArray) // статическая функция { lEnumerator *plter = pArray › GetEnumerator(); bool more = piter › MoveNext(); // логическое значение while (more) { String *pStr = dynamic_cast<String *>((p!ter › Current)); Console::WriteLine (pStr); more = p!ter › MoveNext (); } }
Интерфейс ICollection
Интерфейс ICollection является производным от lEnumerable и в нем добавляются свойство Count (Количество) и метод CopyТо.
_gc _interface ICollection: public lEnumerable // сборщик мусора – ICollection: lEnumerable { _property int get_Count(); _property bool get_IsSynchronized(); // логический _property Object* get_SyncRoot(); void CopyTo(Array* array, int index); // массив, индекс };
Кроме того, в данном интерфейсе появляются свойства, предназначенные для обеспечения синхронизации при использовании потоков. "Является ли безопасным использование потоков?" – вот один из часто задаваемых вопросов о любой библиотеке. Что касается среды .NET Framework, то ответ на этот вопрос короток и ясен – нет. Это не значит, что разработчики .NET Framework не задумывались о безопасности использования потоков. Наоборот, они реализовали множество механизмов, которые могут помочь вам при работе с потоками.
Причина же, по которой использование потоков при работе с коллекциями не является безопасным автоматически, – в том, что обеспечение безопасности приводит к понижению производительности, а если ее обеспечить автоматически, то и при работе в однопотоковом режиме производительность окажется заниженной. Если же вам необходимо обеспечить безопасность при работе с потоками, вы можете использовать свойства интерфейса, предназначенные для синхронизации. Более подробно механизмы синхронизации потоков в .NET Framework будут рассмотрены в главе 8 "Классы каркаса .NET Framework".
Программа StringList иллюстрирует использование свойства Capacity (Объем) класса ArrayList (Список массивов), а также свойства Count (Количество), унаследованного классом ArrayList (Список массивов) от интерфейса ICollection.
static void ShowCount() // статическая функция { Console::WriteLine( "pList › Count = {0}", _box(pList › Count)); // Счет Console::WriteLine( "pList › Capacity = {0}", _box(pList › Capacity)); // Вместимость }