Поделиться через


Использование Visual C# для реализации пользовательских коллекций

В этой пошаговой статье показано, как реализовать пользовательскую коллекцию в Visual C#. Библиотеки базовых классов Microsoft платформа .NET Framework предлагают формальное определение интерфейса коллекцииSystem.Collections.ICollection.

Исходная версия продукта: Visual C#
Исходный номер базы знаний: 307484

Реализация интерфейса ICollection в пользовательском классе

Интерфейс ICollection наследует от интерфейса IEnumerable . Интерфейс ICollection определяет метод и три свойства, доступные CopyTo только для чтения: IsSynchronized, SyncRootи Count. ICollection наследует GetEnumerator метод из IEnumerable интерфейса. Класс пользовательской ICollection коллекции должен реализовать интерфейс.

Чтобы реализовать ICollection интерфейс, выполните следующие действия.

  1. В Visual C# .NET создайте приложение Windows.

  2. В Обозреватель решений щелкните правой кнопкой мыши имя проекта, наведите указатель мыши на "Добавить", а затем нажмите кнопку "Добавить класс", чтобы добавить модуль класса с именем CustomCollection.

  3. Добавьте следующий пример кода в начало модуля класса для импорта System.Collection пространства имен:

    using System.Collections;
    
  4. Замените любой другой код в модуле следующим примером кода:

    public class CustomCollection : ICollection
    {
        private int[] intArr = {1,5,9};
        private int Ct;
    
        public CustomCollection()
        {
            Ct=3;
        }
    }
    

    Для простоты CustomCollection класс содержит массив с тремя целыми элементами и переменной счетчика.

  5. CopyTo Реализуйте метод, который принимает целый массив и индекс в качестве параметров. Этот метод копирует элементы в коллекцию в массив, начиная с переданного индекса. Чтобы реализовать этот метод, вставьте следующий код после общедоступного CustomCollection конструктора:

    void ICollection.CopyTo(Array myArr, int index)
    {
        foreach (int i in intArr)
        {
            myArr.SetValue(i,index);
            index = index+1;
        }
    }
    
  6. GetEnumerator Реализуйте метод, наследуемый интерфейсомICollection.IEnumerable Метод GetEnumerator возвращает Enumerator объект, который может выполнять итерацию через коллекцию. Вставьте следующий пример кода после CopyTo метода:

    IEnumerator IEnumerable.GetEnumerator()
    {
        return new Enumerator(intArr);
    }
    
  7. Чтобы реализовать три свойства только для чтения, вставьте следующий код после GetEnumerator метода:

    // The IsSynchronized Boolean property returns True if the
    // collection is designed to be thread safe; otherwise, it returns False.
    bool ICollection.IsSynchronized
    {
        get
        {
            return false;
        }
    }
    
    // The SyncRoot property returns an object, which is used for synchronizing
    // the collection. This returns the instance of the object or returns the
    // SyncRoot of other collections if the collection contains other collections.
    object ICollection.SyncRoot
    {
        get
        {
            return this;
        }
    }
    
    // The Count read-only property returns the number
    // of items in the collection.
    int ICollection.Count
    {
        get
        {
            return Ct;
        }
    }
    

Реализация объекта Перечислителя для метода GetEnumerator

В этом разделе показано, как создать Enumerator класс, который может выполнять итерацию CustomCollection.

  1. Вставьте следующий пример кода после инструкции конечного класса в модуле класса:

    public class Enumerator : IEnumerator
    {
        private int[] intArr;
        private int Cursor;
    }
    

    Объявите частный intArr целый массив для хранения элементов CustomCollection класса при вызове GetEnumerator метода. Элемент Cursor поля содержит текущую позицию при перечислении.

  2. Добавьте конструктор в intArr качестве параметра и задайте для этого локальное intArr значение. Вставьте следующий пример кода после объявления поля члена:

    public Enumerator(int[] intarr)
    {
        this.intArr = intarr;
        Cursor = -1;
    }
    
  3. Реализуйте методы Reset и MoveNext. Для этого вставьте следующий код после конструктора:

    void IEnumerator.Reset()
    {
        Cursor = -1;
    }
    bool IEnumerator.MoveNext()
    {
        if (Cursor < intArr.Length)
            Cursor++;
    
        return(!(Cursor == intArr.Length));
    }
    

    ResetCursor задает значение -1 и MoveNext перемещает его Cursor к следующему элементу. MoveNext Возвращает значение True в случае успешного выполнения.

  4. Current Реализуйте свойство только для чтения, возвращающее элемент, на который указывает элементCursor. Если значение Cursor равно -1, оно создает InvalidOperationExceptionобъект . Вставьте следующий код после MoveNext метода:

    object IEnumerator.Current
    {
        get
        {
            if((Cursor < 0) || (Cursor == intArr.Length))
                throw new InvalidOperationException();
            return intArr[Cursor];
        }
    }
    

Использование для каждого из них для итерации через пользовательскую коллекцию

  1. В Form1.cs на вкладке "Конструктор " перетащите кнопку в форму.

  2. Дважды щелкните кнопку и добавьте следующий пример кода в Click событие кнопки:

    CustomCollection MyCol = new CustomCollection();
    
    foreach (object MyObj in MyCol)
        MessageBox.Show(MyObj.ToString());
    
  3. Нажмите клавишу F5, чтобы запустить приложение, а затем нажмите кнопку.

    Примечание.

    В окне сообщения отображаются элементы в пользовательской коллекции.

Как это работает? Для каждого вызова GetEnumerator метода для создания Enumerator объекта и вызывается MoveNext метод для задания Cursor первого элемента. Затем текущее свойство получает доступ к элементу MyObj. Это повторяется, пока не MoveNext возвращает значение False.