Шаг 297.
Язык программирования C#. Начала.
Немного о разном. Знакомство с коллекциями

    На этом шаге мы дадим общие сведения о коллекции и приведем пример ее использования.

    Далее мы познакомимся с тем, как в языке C# реализуются коллекции (иногда их еще называют контейнерами). Вообще, под коллекцией подразумевают группу объектов. Такая группа объектов реализуется как некий объект определенного класса, содержащий в себе коллекцию объектов другого класса. Технически это можно реализовать с помощью класса, у которого есть поле, представляющее собой ссылку на массив объектов, формирующих коллекцию. То есть в прикладном плане мы могли бы сами без особых проблем описать подобный класс. То есть сама по себе возможность "спрятать" в одном объекте группу других объектов уникальной не является. Удобство и эффективность использования коллекций во многом связаны с наличием методов, облегчающих работу с группами объектов, содержащихся в коллекции. Другая важная особенность коллекций, выделяющая их на фоне обычных массивов, - возможность добавлять элементы в коллекцию и удалять элементы из коллекции.


После создания массива его размер изменить нельзя. Но мы можем поступить так: создаем новый массив нужного размера, заполняем его правильным образом и ссылку на этот массив записываем в переменную массива. Создается иллюзия, что массив изменил размер. Хотя это, конечно, не так. При работе с коллекциями процесс "изменения" размера массива, который лежит в основе коллекции, автоматизирован, что довольно удобно.

    В C# существуют классы для реализации самых разных коллекций. С некоторыми из них мы познакомимся поближе.

    Коллекции могут быть самыми разными, но у всех них есть определенные общие характеристики. Такое "единство стандарта" поддерживается за счет реализации классами коллекций специальных интерфейсов. Интерфейсы, реализованные в классе коллекции, определяют, какими методами обладает коллекция. Одним из фундаментальных интерфейсов при работе с коллекциями является ICollection (из пространства имен System.Collections). Кроме этого интерфейса, можно упомянуть такие, как IComparer, IDictionary, IEnumerator, IList и INumerable. Например, интерфейс ICollection содержит объявление доступного только для чтения свойства Count, определяющего количество элементов коллекции. Метод CopyTo() предназначен для копирования содержимого коллекции в массив, переданный методу в качестве аргумента. Интерфейс IList содержит объявление таких методов, как

Аналогичные методы объявлены и в других интерфейсах.

    Существуют стандартные классы, реализующие перечисленные выше интерфейсы. Один из них - класс ArrayList. Класс ArrayList реализует интерфейсы ICollection, IList, IEnumerable и ICloneable. Этот класс предназначен для реализации динамических массивов, размер которых может меняться в процессе выполнения программы. Пример создания и использования коллекции на основе класса ArrayList представлен в примере ниже.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Collections;

namespace pr297_1
{
    // Главный класс: 
    class Program
    {
        // Главный метод: 
        static void Main()
        {
            // Целочисленная переменная: 
            int n = 10;
            // Создание объекта коллекции (без элементов):
            ArrayList fibs = new ArrayList();
            // Добавление элементов в коллекцию:
            fibs.Add(1);
            fibs.Add(1);
            for(int k = 2; k <= n;k++) {
                // Вычисление нового элемента и добавление 
                // в коллекцию:
                fibs.Add((int)fibs[fibs.Count - 1] + (int)fibs[fibs.Count - 2]);
            }
            // Отображение содержимого коллекции: 
            foreach(object obj in fibs) {
                Console.Write("|" + obj);
            }
            Console.WriteLine("|");
            // Удаление элементов из коллекции:
            fibs.Remove(1);
            fibs.Remove(5);
            // Вставка элемента в начало коллекции: 
            fibs.Insert(0, 100);
            // Обратный порядок элементов в коллекции: 
            fibs.Reverse();
            // Преобразование коллекции в массив: 
            int[] nums = (int[])fibs.ToArray(typeof(int));
            // Отображение содержимого массива: 
            for(int k = 0; k < nums.Length; k++){
                Console.Write("|" + nums[k]);
            }
            Console.WriteLine("|");
            // Задержка:
            Console.ReadLine();
        }
    }
}
Архив проекта можно взять здесь.

    Результат выполнения программы такой:


Рис.1. Результат работы приложения

    В данном случае для работы с коллекциями мы подключаем пространство имен System.Collections. В главном методе программы объект коллекции fibs создается командой

  ArrayList fibs = new ArrayList();    . 
Созданный таким образом объект будет пустым (он не содержит ни одного элемента).


При создании объекта коллекции в качестве аргумента конструктору класса ArrayList можно передать, например, массив. В этом случае будет создана коллекция на основе массива. В любом случае в коллекцию можно добавлять элементы и удалять элементы из коллекции. Размер коллекции при этом регулируется автоматически. Также следует различать размер коллекции и количество элементов в коллекции. Размер коллекции определяется количеством мест в базовом массиве коллекции, предназначенном для хранения элементов. Обычно размер коллекции больше количества содержащихся в ней элементов. Узнать количество элементов в коллекции можно с помощью свойства Count. Узнать или задать размер коллекции можно с помощью свойства Capacity.

    Для добавления элементов в коллекцию используем метод Add() (элемент добавляется в конец коллекции). То есть первые два элемента в коллекции - единицы. Затем запускается конструкция цикла, и за каждую итерацию цикла в коллекцию добавляется новый элемент. Предварительно этот элемент вычисляется как сумма двух предыдущих элементов. Для этого используется выражение (int)fibs[fibs.Count-1] + (int)fibs[fibs.Count-2].


Для получения значения элемента в коллекции можно использовать индекс, как при работе с массивами. Поэтому доступ к первому элементу в коллекции fibs получаем с помощью инструкции fibs[0] (можно прочитать значение элемента или присвоить значение элементу). Количество элементов в коллекции определяем с помощью свойства Count. Поскольку индексация элементов в коллекции, как и в массиве, начинается с нуля, то индекс последнего элемента в коллекции на единицу меньше количества элементов в коллекции. Индекс последнего элемента в коллекции fibs вычисляется как fibs.Count-1, а индекс предпоследнего элемента вычисляется как fibs.Count-2.

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


    Для отображения элементов из коллекции использована конструкция цикла по коллекции foreach. При этом мы также учли, что элементы в коллекции сохраняются в виде объектных ссылок класса Object (в программе использован псевдоним object для выражения System.Object).

    Для удаления элементов используется метод Remove(). Командой

  fibs.Remove(1); 
из коллекции удаляется элемент со значением 1 (первый из двух), а командой
  fibs.Remove(5);
из коллекции удаляется элемент со значением 5. А вот командой
  fibs.Insert(0, 100); 
в позицию с индексом 0 в коллекции fibs добавляется элемент со значением 100. Командой
  fibs.Reverse(); 
порядок элементов в коллекции fibs изменяется на обратный.

    Коллекцию можно преобразовать в массив (точнее, создать массив на основе коллекции). Для этого используют метод ToArray(). Пример использования этого метода дается командой

  int[] nums = (int[])fibs.ToArray(typeof(int));      , 
которой на основе коллекции fibs создается целочисленный массив nums. Но и здесь не все так просто. Метод ToArray() результатом возвращает ссылку на массив из элементов класса Object. То есть результатом метода является значение типа Object[]. Чтобы записать такую ссылку в переменную nums, необходимо выполнить явное приведение к типу int[]. Аргументом методу ToArray() передается выражение typeof(int). Этот аргумент определяет тип элементов массива, который создается на основе коллекции.


Результатом выражения на основе typeof-инструкции является объект класса Type, который содержит описание типа, идентификатор которого указан в typeof-инструкции.

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




Предыдущий шаг Содержание Следующий шаг