Domanda

La mia domanda è è sicuro per enumeratore per rimuovere elemento dalla SortedList?

SortedList<decimal, string> myDictionary;
// omitted code

IEnumerator<decimal, string> enum = myDictionary.GetEnumerator();

while(enum.MoveNext)
{
  // is it ok to remove here?
  myDictionary.Remove(enum.Current.Key);
}
È stato utile?

Soluzione

In questo modo un'eccezione -. Non è possibile modificare una raccolta, mentre l'iterazione su di esso

Se ci pensate un po ', si capirà il perché. Se aggiunta o la rimozione della collezione è stato permesso, si sarebbe non essere più l'iterazione sulla stessa collezione -. Si hanno o troppi (aggiunta) o non abbastanza articoli (rimozione)

Altri suggerimenti

Come già detto quello che stai cercando di fare non è possibile. Tuttavia, una soluzione alternativa sarebbe quella di mantenere semplicemente un elenco di articoli contrassegnati per l'eliminazione e quindi rimuovere questi afterwords. Vorrei anche optare per un foreach piuttosto che un ciclo while, meno codice per es.

var removeList = new List<decimal>();
foreach (var item in myDictionary)
{
    // have a condition which indicates which items are to be removed
    if (item.Key > 1)
    {
        removeList.Add(item.Key);
    }
}

Oppure, se si sta semplicemente cercando di recuperare gli elementi per la cancellazione, l'uso LINQ

var removeList = myDictionary.Where(pair => pair.Key > 1).Select(k => k.Key).ToList();

Poi basta rimuoverli dalla lista.

// remove from the main collection
foreach (var key in removeList)
{
    myDictionary.Remove(key);
}

Operazioni in lista durante le iterazioni non sono supportati in generale. Il comportamento previsto è un'eccezione, ma anche se una collezione non riesce a fare questo non è necessario fare affidamento su questo funziona correttamente.

È possibile prima copiare gli elementi in un'altra lista e poi iterare su questo nuovo elenco di elementi da modificare.

No. Un InvalidOperationExcpetion è gettato. Sono d'accordo che gli elementi già elencati potrebbero essere eliminabile in quanto non v'è un indice fisso. Tuttavia, il problema è il seguente:

L'attuazione di SortedList non è abbastanza intelligente per capire che ciò non ha alcun effetto sul l'ulteriore esecuzione del enumerabile. E per mantenere le cose semplici e che funziona bene, non dovrebbe.

Come altri hanno già fatto notare che non funzionerà. Tuttavia, dato che la collezione è un SortedList è possibile utilizzare il metodo RemoveAt.

Questo metodo ha un profilo leggermente migliore memoria poiché richiede alcun overhead in contrapposizione ad un incremento O (n) utilizzando un elenco separato per tenere traccia delle rimozioni. Sarebbe anche un O (n ^ 2) il profilo delle prestazioni rispetto a O (n ^ 2 * log (n)). Il metodo RemoveAt è O (n) in quanto deve eseguire una copia matrice. Il metodo Remove aggiunge un'operazione O (log (n)) per trovare l'indice prima di chiamare internamente RemoveAt. Tutto questo è probabilmente di nessun interesse per voi, ma è conoscenza utile nel caso in cui si esegue in circostanze che comportino un sacco di 'n'.

var myDictionary = new SortedList<decimal, string>();

// omitted code

int i = 0;
while (myDictionary.Count > 0 && i < myDictionary.Count)
{
  if (/* predicate to use for removal */)
  {
    myDictionary.RemoveAt(i);
  }
  else
  {
    i++;
  }
}

Un altra soluzione:

            int counter= MyDictionary.Count;
            if (counter == 0)
                return;

            for (int i = 0;  i < counter;i++)
            {
                KeyValuePair<MyIdentifier, MyValue> key = (KeyValuePair<MyIdentifier, MyValue>)MyDictionary.ToArray()[i];
                MyIdentifier identifier = null;

                if (key.Key != null)
                    identifier = key.Key as MyIdentifier;

                if (identifier != null)
                    if (MyCondition)
                    {
                        MyDictionary.Remove(identifier);
                        counter--;
                    }
            }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top