none
metodo lista.remove() va in eccezione RRS feed

  • 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'elento

     

     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])
    


    MarcoSF
    mercoledì 27 luglio 2011 15:23

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
    giovedì 28 luglio 2011 14:14

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
    mercoledì 27 luglio 2011 15:27
  • E' un problema noto con il nome di "Halloween Problem"

    wikipedia

     

    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
    mercoledì 27 luglio 2011 18:56
  • 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
    mercoledì 27 luglio 2011 19:21
  • 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
    giovedì 28 luglio 2011 08:21
  • 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 detto

    che 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
    giovedì 28 luglio 2011 09:32
  • 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 righeSenzaOrdinelLavoro

    COme devo fare ho provato a fare il ciclo for partendo dalla fine verso zero ma non mi funziona

     


    MarcoSF
    giovedì 28 luglio 2011 13:56
  • 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
    giovedì 28 luglio 2011 14:14
  • 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

    sabato 30 luglio 2011 00:10