Principale utente con più risposte
metodo lista.remove() va in eccezione

Domanda
-
foreach (Stazionamento s in stazionamenti) { righeSenzaOrdinelavoro[i] = s.Clone(); stazionamenti.Remove(s); i++; }
Perche quando cancello l'elemento il ciclo foreach sull elenco va in eccezione dopo che ho cancellato l'elentoho provato anche a fare cosi ma cosi non cancella l'elemneto nonstante righeSenzaOrdineLavoro sia un array del tipo della lista
stazionamenti.Remove(righeSenzaOrdinelavoro[i])
MarcoSF
Risposte
-
favaronSF wrote:
[...]Questo è il codice completo del metodo io devo cancellare tutti gli elemnti S di tipo stazionamento dalla lista stazionamenti che sono uguali a quelli che ho inserito nell' array righeSenzaOrdinelLavoro
COme devo fare ho provato a fare il ciclo for partendo dalla fine verso zero ma non mi funziona
Non vedo la remove e comunque stai usando il foreach.
La regola per il foreach è che puoi usare la lista enumerata solo in lettura quindi:
- soluzione 1: iteri la lista in ordine inverso
- soluzione 2: accumuli le cancellazioni in una lista separata, poi iteri la seconda lista che contiene le cancellazioni ed esegui la cancellazione sulla lista principale
soluzione 1:
private void test1()
{
List<int> list = new List<int>() { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 };
for (int i = list.Count - 1; i >= 0; --i)
{
var element = list[i];
if (element == 15)
list.Remove(element);
}
Console.WriteLine(string.Join(", ", list));
}
risultato:
10, 11, 12, 13, 14, 16, 17, 18, 19
Soluzione 2:
private void test2()
{
List<int> list = new List<int>() { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 };
List<int> temp = new List<int>();
foreach(var element in list)
{
if (element == 15)
temp.Add(element);
}
foreach (var element in temp)
{
list.Remove(element);
}
Console.WriteLine(string.Join(", ", list));
}
risultato:
10, 11, 12, 13, 14, 16, 17, 18, 19
Raffaele Rialdi http://www.iamraf.net
Weblog: http://blogs.ugidotnet.org/raffaele
Microsoft MVP profile https://mvp.support.microsoft.com/profile/raffaele
UGIdotNET - http://www.ugidotnet.org/
Raffaele Rialdi [MVP] My articles and videos: http://www.iamraf.net Italian blog: http://blogs.ugidotnet.org/raffaele- Proposto come risposta Matteo Migliore venerdì 29 luglio 2011 07:14
- Contrassegnato come risposta Mila Daniel Ovidiu domenica 31 luglio 2011 22:18
Tutte le risposte
-
favaronSF wrote:
foreach (Stazionamento s in stazionamenti) { righeSenzaOrdinelavoro[i] = s.Clone(); stazionamenti.Remove(s); i++; }
Perche quando cancello l'elemento il ciclo foreach sull elenco va in eccezione dopo che ho cancellato l'elento
Perché stai enumerando e quindi la cancellazione renderebbe invalido l'enumeratore.
È come togliersi la sedia sotto il sedere ...ho provato anche a fare cosi ma cosi non cancella l'elemneto nonstante righeSenzaOrdineLavoro sia un array del tipo della lista
stazionamenti.Remove(righeSenzaOrdinelavoro[i])
Questo funziona se enumeri l'elemento dall'ultimo al primo elemento
Gira lo statement "for" partendo da Count-1 fino a zero ...
Raffaele Rialdi http://www.iamraf.net
Weblog: http://blogs.ugidotnet.org/raffaele
Microsoft MVP profile https://mvp.support.microsoft.com/profile/raffaele
UGIdotNET - http://www.ugidotnet.org/
Raffaele Rialdi [MVP] My articles and videos: http://www.iamraf.net Italian blog: http://blogs.ugidotnet.org/raffaele -
E' un problema noto con il nome di "Halloween Problem"
Saluti
Massimo Giambona
MCT
MCTS Microsoft Office Sharepoint Configuration
MCTS Microsoft .NET Framework 4.0
MCPD ASP.NET Developer 4.0
MCPD Microsoft Office Sharepoint 2010
MCITP SQL Server 2008
Corporate Site
Blog -
Massimo Giambona wrote:
E' un problema noto con il nome di "Halloween Problem"
wikipedia <http://en.wikipedia.org/wiki/Halloween_Problem>??? sicuro?
Io direi più che altro un problema da pagina 2 di qualsiasi linguaggio di programmazione :)
Raffaele Rialdi http://www.iamraf.net
Weblog: http://blogs.ugidotnet.org/raffaele
Microsoft MVP profile https://mvp.support.microsoft.com/profile/raffaele
UGIdotNET - http://www.ugidotnet.org/
Raffaele Rialdi [MVP] My articles and videos: http://www.iamraf.net Italian blog: http://blogs.ugidotnet.org/raffaele -
stazionamenti.Remove(righeSenzaOrdinelavoro[i])
Questo funziona se enumeri l'elemento dall'ultimo al primo elemento
Gira lo statement "for" partendo da Count-1 fino a zero ...
ho provato anche così come hai detto tu ma non va!!!!
Avevo provato a fare il ciclo foreach perchè i geni microsoft avevano detto che il FrameWork4 avrebbe gestito la moggior parte di queste condizioni da solo.
Se dovevo farlo i C mi sarei arrangiato a gestire le liste pensavo che qua non servisse......... :)
??? sicuro?
Io direi più che altro un problema da pagina 2 di qualsiasi linguaggio di programmazione :)
MarcoSF -
favaronSF wrote:
stazionamenti.Remove(righeSenzaOrdinelavoro[i])
Questo funziona se enumeri l'elemento dall'ultimo al primo elemento
Gira lo statement "for" partendo da Count-1 fino a zero ...ho provato anche così come hai detto tu ma non va!!!!
puoi spiegare cosa non va?
> Avevo provato a fare il ciclo foreach perchè i geni microsoft avevano dettoche il FrameWork4 avrebbe gestito la moggior parte di queste condizioni da solo.
LOL
L'iterazione di una collection di elementi la decide il developer, non microsoft.Se dovevo farlo i C mi sarei arrangiato a gestire le liste pensavo che qua non servisse......... :)
In C è esattamente identico, le rimozioni devi farle iterando dall'ultimo elemento, altrimenti gli elementi scalano.
In C++ ci sono le STL e le rimozioni non puoi farle in un for_each.
Questo per dire che lo stesso problema ce l'hai in qualsiasi linguaggio su qualsiasi framework.
Raffaele Rialdi http://www.iamraf.net
Weblog: http://blogs.ugidotnet.org/raffaele
Microsoft MVP profile https://mvp.support.microsoft.com/profile/raffaele
UGIdotNET - http://www.ugidotnet.org/
Raffaele Rialdi [MVP] My articles and videos: http://www.iamraf.net Italian blog: http://blogs.ugidotnet.org/raffaele -
public Stazionamento[] WriteStazionamentiToDataBase(List<Stazionamento> stazionamenti) { //Mi recupero gli ordini lavoro dagli ordini di viaggio Stazionamento[] righeSenzaOrdinelavoro = new Stazionamento [50]; int[] keyOrdiniLavoro = new int[2]; int maxElemt, i=0; string filtro = "", chiave; Dictionary<string, int> maxStazioneamenti = new Dictionary<string, int>(); foreach (Stazionamento s in stazionamenti) { if (s.ViaggioParent.AnnoOrdineLavoro == 0 && s.ViaggioParent.NumeroOrdineLavoro == 0) { keyOrdiniLavoro = GestoreDati.Istance.GetKeyOrdiniLavoro(s.ViaggioParent.AnnoViaggio, s.ViaggioParent.NumeroViaggio, s.ViaggioParent.Nave.IdNave); if (keyOrdiniLavoro[0] != -1) { s.ViaggioParent.AnnoOrdineLavoro = keyOrdiniLavoro[0]; s.ViaggioParent.NumeroOrdineLavoro = keyOrdiniLavoro[1]; } else { if (i < 50) { righeSenzaOrdinelavoro[i] = s.Clone(); i++; } continue; //MessageBox.Show("Manca l'ordine lavoro per la nave selezionata ", "Errore", MessageBoxButton.OK, MessageBoxImage.Error); } } GestoreDati.Istance.DeleteStazionamentiToDataBase(s.ViaggioParent.AnnoOrdineLavoro, s.ViaggioParent.NumeroOrdineLavoro); } foreach (Stazionamento s in stazionamenti) { filtro = filtro + "(LOAALA =" + s.ViaggioParent.AnnoOrdineLavoro + " AND LONRLA = " + s.ViaggioParent.NumeroOrdineLavoro + ") OR "; } filtro = filtro + "(LOAALA = 0)"; maxStazioneamenti = GestoreDati.Istance.GetMaxOrdiniLavoro(filtro); foreach (Stazionamento s in stazionamenti) { chiave = s.ViaggioParent.AnnoOrdineLavoro.ToString() + "|" + s.ViaggioParent.NumeroOrdineLavoro.ToString(); if (maxStazioneamenti.ContainsKey(chiave)) { maxElemt = maxStazioneamenti[chiave]; maxElemt++; GestoreDati.Istance.InsertStazionamentiToDataBase(s, maxElemt); maxStazioneamenti[chiave] = maxElemt; } else { GestoreDati.Istance.InsertStazionamentiToDataBase(s, 1); maxStazioneamenti.Add(chiave, 1); } } return righeSenzaOrdinelavoro; }
Questo è il codice completo del metodo io devo cancellare tutti gli elemnti S di tipo stazionamento dalla lista stazionamenti che sono uguali a quelli che ho inserito nell' array righeSenzaOrdinelLavoroCOme devo fare ho provato a fare il ciclo for partendo dalla fine verso zero ma non mi funziona
MarcoSF -
favaronSF wrote:
[...]Questo è il codice completo del metodo io devo cancellare tutti gli elemnti S di tipo stazionamento dalla lista stazionamenti che sono uguali a quelli che ho inserito nell' array righeSenzaOrdinelLavoro
COme devo fare ho provato a fare il ciclo for partendo dalla fine verso zero ma non mi funziona
Non vedo la remove e comunque stai usando il foreach.
La regola per il foreach è che puoi usare la lista enumerata solo in lettura quindi:
- soluzione 1: iteri la lista in ordine inverso
- soluzione 2: accumuli le cancellazioni in una lista separata, poi iteri la seconda lista che contiene le cancellazioni ed esegui la cancellazione sulla lista principale
soluzione 1:
private void test1()
{
List<int> list = new List<int>() { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 };
for (int i = list.Count - 1; i >= 0; --i)
{
var element = list[i];
if (element == 15)
list.Remove(element);
}
Console.WriteLine(string.Join(", ", list));
}
risultato:
10, 11, 12, 13, 14, 16, 17, 18, 19
Soluzione 2:
private void test2()
{
List<int> list = new List<int>() { 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 };
List<int> temp = new List<int>();
foreach(var element in list)
{
if (element == 15)
temp.Add(element);
}
foreach (var element in temp)
{
list.Remove(element);
}
Console.WriteLine(string.Join(", ", list));
}
risultato:
10, 11, 12, 13, 14, 16, 17, 18, 19
Raffaele Rialdi http://www.iamraf.net
Weblog: http://blogs.ugidotnet.org/raffaele
Microsoft MVP profile https://mvp.support.microsoft.com/profile/raffaele
UGIdotNET - http://www.ugidotnet.org/
Raffaele Rialdi [MVP] My articles and videos: http://www.iamraf.net Italian blog: http://blogs.ugidotnet.org/raffaele- Proposto come risposta Matteo Migliore venerdì 29 luglio 2011 07:14
- Contrassegnato come risposta Mila Daniel Ovidiu domenica 31 luglio 2011 22:18
-
Giusto per aggiungere una nota di colore alla risposta di Raf (completa come sempre), questo e' un articolo che parla dell'Halloween Problem con XML e con collezioni. Non a caso il pattern che ha generato questo thread e' parte in causa.
Saluti
http://blogs.msdn.com/b/mikechampion/archive/2006/07/20/672208.aspx
--Alessandro