Uso de Visual C# para implementar colecciones personalizadas

En este artículo paso a paso se muestra cómo implementar una colección personalizada en Visual C#. Las bibliotecas de clases base de Microsoft .NET Framework ofrecen una definición formal de una interfaz de colección System.Collections.ICollection .

Versión original del producto: Visual C#
Número de KB original: 307484

Implementación de la interfaz ICollection en una clase personalizada

La ICollection interfaz hereda de la IEnumerable interfaz. La ICollection interfaz define un CopyTo método y tres propiedades de solo lectura: IsSynchronized, SyncRooty Count. ICollection hereda el GetEnumerator método de la IEnumerable interfaz. Una clase de colección personalizada debe implementar la ICollection interfaz .

Para implementar la ICollection interfaz, siga estos pasos:

  1. En Visual C# .NET, cree una aplicación de Windows.

  2. En Explorador de soluciones, haga clic con el botón derecho en el nombre del proyecto, seleccione Agregary, a continuación, haga clic en Agregar clase para agregar un módulo de clase denominado CustomCollection.

  3. Agregue el código de ejemplo siguiente al principio del módulo de clase para importar el espacio de System.Collection nombres:

    using System.Collections;
    
  4. Reemplace cualquier otro código del módulo por el código de ejemplo siguiente:

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

    Por motivos de simplicidad, la CustomCollection clase contiene una matriz con tres elementos enteros y una variable count.

  5. Implemente el CopyTo método , que toma una matriz de enteros y un índice como parámetros. Este método copia los elementos de una colección en la matriz a partir del índice que se pasa. Para implementar este método, pegue el código siguiente después del constructor público CustomCollection :

    void ICollection.CopyTo(Array myArr, int index)
    {
        foreach (int i in intArr)
        {
            myArr.SetValue(i,index);
            index = index+1;
        }
    }
    
  6. Implemente el GetEnumerator método , que hereda la ICollection interfaz de IEnumerable. El GetEnumerator método devuelve un Enumerator objeto que puede recorrer en iteración una colección. Pegue el código de ejemplo siguiente después del CopyTo método :

    IEnumerator IEnumerable.GetEnumerator()
    {
        return new Enumerator(intArr);
    }
    
  7. Para implementar las tres propiedades de solo lectura, pegue el código siguiente después del GetEnumerator método :

    // 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;
        }
    }
    

Implementación de un objeto Enumerator para el método GetEnumerator

En esta sección se muestra cómo crear una Enumerator clase que puede recorrer en iteración CustomCollection.

  1. Pegue el código de ejemplo siguiente después de la instrucción de clase final en el módulo de clase:

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

    Declare la intArr matriz de enteros privados para contener los elementos de la CustomCollection clase cuando se llama al GetEnumerator método . El Cursor miembro de campo mantiene la posición actual al enumerar.

  2. Agregue un constructor con intArr como parámetro y establezca el valor local intArr en este. Pegue el código de ejemplo siguiente después de la declaración del campo miembro:

    public Enumerator(int[] intarr)
    {
        this.intArr = intarr;
        Cursor = -1;
    }
    
  3. Implemente los Reset métodos y MoveNext . Para ello, pegue el código siguiente después del constructor:

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

    Reset establece en Cursor-1 y MoveNext mueve al Cursor elemento siguiente. MoveNext devuelve True si se ejecuta correctamente.

  4. Implemente la Current propiedad de solo lectura que devuelve el elemento al que apunta Cursor. Si es Cursor-1, genera un InvalidOperationException. Pegue el código siguiente después del MoveNext método :

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

Uso de para cada uno para recorrer en iteración la colección personalizada

  1. En Form1.cs, en la pestaña Diseño , arrastre un botón al formulario.

  2. Haga doble clic en el botón y agregue el código de ejemplo siguiente al Click evento del botón:

    CustomCollection MyCol = new CustomCollection();
    
    foreach (object MyObj in MyCol)
        MessageBox.Show(MyObj.ToString());
    
  3. Presione F5 para ejecutar la aplicación y, a continuación, haga clic en el botón .

    Nota:

    Un cuadro de mensaje muestra los elementos de la colección personalizada.

¿Cómo funciona esto? Para cada una de ellas llama al GetEnumerator método para crear el Enumerator objeto y llama al MoveNext método para establecer en Cursor el primer elemento. A continuación, se obtiene acceso a la propiedad actual para obtener el elemento en MyObj. Esto se repite hasta MoveNext que devuelve False.