Usare Visual C# per implementare raccolte personalizzate

Questo articolo dettagliato illustra come implementare una raccolta personalizzata in Visual C#. Le librerie di classi di base di Microsoft .NET Framework offrono una definizione formale di un'interfaccia di raccolta System.Collections.ICollection .

Versione originale del prodotto: Oggetto visivo C#
Numero KB originale: 307484

Implementare l'interfaccia ICollection in una classe personalizzata

L'interfaccia ICollection eredita dall'interfaccia IEnumerable . L'interfaccia ICollection definisce un CopyTo metodo e tre proprietà di sola lettura: IsSynchronized, e .CountSyncRoot ICollection eredita il GetEnumerator metodo dall'interfaccia IEnumerable . Una classe di raccolta personalizzata deve implementare l'interfaccia ICollection .

Per implementare l'interfaccia ICollection , seguire questa procedura:

  1. In Visual C# .NET creare un'applicazione Windows.

  2. In Esplora soluzioni fare clic con il pulsante destro del mouse sul nome del progetto, scegliere Aggiungi e quindi fare clic su Aggiungi classe per aggiungere un modulo di classe denominato CustomCollection.

  3. Aggiungere il codice di esempio seguente all'inizio del modulo di classe per importare lo spazio dei System.Collection nomi:

    using System.Collections;
    
  4. Sostituire qualsiasi altro codice nel modulo con il codice di esempio seguente:

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

    Per semplicità, la CustomCollection classe contiene una matrice con tre elementi interi e una variabile count.

  5. Implementare il CopyTo metodo , che accetta una matrice integer e un indice come parametri. Questo metodo copia gli elementi di una raccolta nella matrice a partire dall'indice passato. Per implementare questo metodo, incollare il codice seguente dopo il costruttore pubblico CustomCollection :

    void ICollection.CopyTo(Array myArr, int index)
    {
        foreach (int i in intArr)
        {
            myArr.SetValue(i,index);
            index = index+1;
        }
    }
    
  6. Implementare il GetEnumerator metodo , ereditato dall'interfaccia ICollection da IEnumerable. Il GetEnumerator metodo restituisce un Enumerator oggetto che può scorrere una raccolta. Incollare il codice di esempio seguente dopo il CopyTo metodo :

    IEnumerator IEnumerable.GetEnumerator()
    {
        return new Enumerator(intArr);
    }
    
  7. Per implementare le tre proprietà di sola lettura, incollare il codice seguente dopo il GetEnumerator metodo :

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

Implementare un oggetto Enumerator per il metodo GetEnumerator

Questa sezione illustra come creare una Enumerator classe in grado di scorrere CustomCollection.

  1. Incollare il codice di esempio seguente dopo l'istruzione end class nel modulo di classe:

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

    Dichiarare la intArr matrice integer privata per contenere gli elementi della CustomCollection classe quando viene chiamato il GetEnumerator metodo . Il Cursor membro del campo contiene la posizione corrente durante l'enumerazione.

  2. Aggiungere un costruttore con intArr come parametro e impostare il valore locale intArr su questo. Incollare il codice di esempio seguente dopo la dichiarazione del campo membro:

    public Enumerator(int[] intarr)
    {
        this.intArr = intarr;
        Cursor = -1;
    }
    
  3. Implementare i Reset metodi e MoveNext . A tale scopo, incollare il codice seguente dopo il costruttore:

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

    Reset imposta su Cursor-1 e MoveNext sposta l'oggetto Cursor all'elemento successivo. MoveNext restituisce True se ha esito positivo.

  4. Implementare la Current proprietà di sola lettura che restituisce l'elemento puntato da Cursor. Se è Cursor-1, genera un oggetto InvalidOperationException. Incollare il codice seguente dopo il MoveNext metodo :

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

Uso di for each per scorrere la raccolta personalizzata

  1. In Form1.cs trascinare un pulsante nel modulo nella scheda Progettazione .

  2. Fare doppio clic sul pulsante e aggiungere il codice di esempio seguente all'evento Click del pulsante:

    CustomCollection MyCol = new CustomCollection();
    
    foreach (object MyObj in MyCol)
        MessageBox.Show(MyObj.ToString());
    
  3. Premere F5 per eseguire l'applicazione e quindi fare clic sul pulsante.

    Nota

    In una finestra di messaggio vengono visualizzati gli elementi della raccolta personalizzata.

Funzionamento. Per ogni chiama il GetEnumerator metodo per creare l'oggetto Enumerator e chiama il MoveNext metodo per impostare sul Cursor primo elemento. Si accede quindi alla proprietà corrente per ottenere l'elemento in MyObj. Questa operazione viene ripetuta fino a quando non MoveNext restituisce False.