Разработка приложений на языке C#. Полезные настройки. Особые спецификаторы формата, страница 25

Функциональность коллекций отвечает стандартам, заданным с помощью интерфейсов. Она копится постепенно путем наследования от все большего числа интерфейсов. ArrayList является весьма удобным контейнером, так как позволяет выбирать свои элементы с помощью целочисленного индекса и, в то же время, вставлять и удалять элементы в произвольные позиции. Эту способность он приобрел благодаря наследованию и реализации интерфейса IList. Интерфейс IList в свою очередь происходит от двух других интерфейсов: ICollection и IEnumerable.

public class ArrayList : IList, ICollection, IEnumerable, ICloneable

Интерфейс IEnumerable имеет всего один метод IEnumerator GetEnumerator();, который возвращает объект класса, реализующий интерфейс IEnumerator. Последний имеет 2 метода (Reset и MoveNext) и одно свойство (Current). Они позволяют последовательно просматривать коллекцию, но не изменять ее элементы. Пример.

ArrayList list = new ArrayList(5);

list.Add (new Man ("Don Box", 30));

list.Add (new Man ("Ron Cox", 20));

list.Add (new Man ("Jon Fox", 18));

IEnumerator en = list.GetEnumerator();

while (en.MoveNext())

  Console.WriteLine (en.Current);

Интерфейс ICollection имеет 3 свойства и 1 метод:

·  int Count {get;} — возвращает количество элементов в коллекции,

·  bool IsSynchronized {get;} — возвращает признак того, что коллекция синхронизирована.

·  object SyncRoot {get;} — возвращает объект, который осуществляет синхронизацию коллекции,

·  void CopyTo (Array array, int index); — копирует объекты в массив array, начиная с элемента с индексом index.

Реализация интерфейса IList дает коллекциям значительно большую функциональность. Он объявляет 7 новых методов и 3 свойства. Большинство из них мы уже использовали при работе, как с обычным массивом, так и с ArrayList. Интерфейс IList объявлен таким образом:

public interface IList : ICollection, IEnumerable

Он наследует все рассмотренные методы интерфейсов ICollection, IEnumerable и добавляет методы: Add, Clear, Contains, IndexOf, Insert, Remove и RemoveAt. а также свойства: IsFixedSize, IsReadOnly. Самым важным свойством является индексатор. Это новое средство языка, которое объявляется таким образом:

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

Он дает возможность изменять элементы массива. Мы рассмотрим особенности функционирования индексаторов позже, а сейчас отметим, что кроме методов, объявленных в родительских интерфейсах, класс ArrayList обладает рядом своих собственных, среди которых несколько необычным кажется метод ToArray, который копирует все элементы коллекции в массив. Отметьте, что при этом нет необходимости предварительно узнавать размер последовательности и выделять соответствующую память для массива-мишени. Сравните эту технологию с той, которая используется при вызове метода CopyTo. Последний требует, чтобы массив (мишень копирования) не только существовал, но и имел достаточный размер. Метод ToArray имеет две версии. Первую вы, вероятно, использовали в примере, а вторая отличается тем, что возвращает массив ссылок типа object. Фрагмент создания и копирования массива в этом случае имеет вид:

object[] mo = men.ToArray();   // Такой синтаксис выглядит очень убедительно

Console.WriteLine ("\nArray copy of men:\n");

foreach (Man m in mo)

m.Out();

((Man)mo[0]).In();    // Изменяем копию

string s = men[0].ToString();  // Проверяем оригинал. Он изменился.

При анализе кода постарайтесь понять следующее: как массив object[] mo, так и коллекция ArrayList men, хранят ссылки типа object, а не ссылки типа Man. Поэтому при их использовании для вызова методов класса Man следует пользоваться операцией явного приведения типа. Например: ((Man)mo[0]).In();. Какой тип копирования происходит в этом примере? Запустив фрагмент в режиме отладки (F10), вы сможете собственными глазами увидеть все, что происходит.

Реализуем интерфейс ICloneable