Rimuovere un oggetto quando in un ciclo for each

Sto facendo un gioco di sopravvivenza e cercando di rimuovere un oggetto quando si spegne lo schermo. Ecco il codice:

Public Sub tmrEnemyMove_Tick(sender As Object, e As EventArgs) Handles tmrEnemyMove.Tick
    Dim koopaAnimation As Boolean

    For Each enemy As enemy In lstEnemy
        enemy.enemy.Left = enemy.enemy.Left - 20

        If enemy.enemy.Tag = "koopa" Then
            enemy.enemy.Image = Image.FromFile(Application.StartupPath + "\Graphics\koopa" + Trim(Str(koopaPosition)) + ".png")
            If koopaAnimation = False Then
                If koopaPosition = 0 Then
                    koopaPosition = 1
                Else
                    koopaPosition = 0
                End If
            End If
            koopaAnimation = True
        End If

        If picMario.Left < enemy.enemy.Left AndAlso enemy.enemy.Left < picMario.Right Or picMario.Left < enemy.enemy.Right AndAlso enemy.enemy.Right < picMario.Right Then
            If picMario.Top < enemy.enemy.Top AndAlso enemy.enemy.Top < picMario.Bottom Or picMario.Top < enemy.enemy.Bottom AndAlso enemy.enemy.Bottom < picMario.Bottom Then
                'MsgBox("Collision")
            End If
        End If

        If enemy.enemy.Left < 0 Then
            lstEnemy.Remove(enemy)
            Me.Controls.Remove(enemy.enemy)
        End If
    Next
End Sub

L’errore che ottengo è:
Un’eccezione non gestita di tipo ‘System.InvalidOperationException’ si è verificato in mscorlib.dll
Ulteriori informazioni: la Raccolta è stata modificata; enumerazione operazione non può essere eseguita.

Se chiunque potesse aiutare sarebbe fantastico, grazie.

Si canot cambiare la collezione come questo, mentre scorrono, per ovvi motivi, se ci pensate. Ottenere un riferimento all’oggetto, mentre nel ciclo, quindi eliminare aterwards

OriginaleL’autore Tyler H | 2013-05-24

3 risposte

  1. 14

    Non è possibile eliminare un oggetto da collezione durante l’enumerazione. Non è possibile modificare la raccolta. Che saranno la causa di un errore(insieme è stato modificato; enumerazione impossibile eseguire l’operazione di). Ma si potrebbero aggiungere gli oggetti che si desidera eliminare/rimuovere un’altra raccolta:

    Dim removeEnemies = New List(Of enemy)
    For Each enemy As enemy In lstEnemy
        ' ... '
        If enemy.enemy.Left < 0 Then
            removeEnemies.Add(enemy.enemy)
        End If
    Next
    
    For Each enemy In removeEnemies
        lstEnemy.Remove(enemy)
        Me.Controls.Remove(enemy.enemy)
    Next

    Questi metodi di causare un elenco di cambiare versione(che è controllato durante l’enumerazione):

    • Aggiungere
    • Chiaro
    • Inserire
    • InsertRange
    • Rimuovere
    • RemoveRange
    • RemoveAt
    • Inverso
    • [l’Indicizzatore setter]
    • Sorta

    Un’altra opzione è quella di utilizzare un For-Loop e loop indietro:

     For i As Int32 = lstEnemy.Count - 1 To 0 Step -1
        Dim enemy = lstEnemy(i)
        ' ... '
        If enemy.enemy.Left < 0 Then
            lstEnemy.Remove(enemy)
            Me.Controls.Remove(enemy.enemy)
        End If
    Next

    Questo non genererà l’errore, ma non è così leggibile. Hai bisogno di andare da list.Count - 1 Per 0 perché si desidera rimuovere gli elementi che potrebbero cambiare il Count proprietà e un indice che era disponibile prima che l’articolo è stato rimosso cause ora un ArgumentOutOfRangeException.

    Ultimo ma non meno importante, è possibile utilizzare l'Elenco.RemoveAll:

    lstEnemy.RemoveAll(Function(enemy) enemy.enemy.Left < 0)
    +1 Grande Risposta
    altra opzione è quella di utilizzare un po ‘ di tempo. grande risposta

    OriginaleL’autore Rango

  2. 1

    .NET non piace quando si modifica una collezione quando sei in mezzo l’enumerazione dei suoi contenuti. Si potrebbe provare a cambiare il vostro foreach loop per un for ciclo se si sta pianificando la rimozione di elementi dalla raccolta.

    OriginaleL’autore Adrian

  3. 0

    Un esempio di utilizzo di entity framework (ElementAt(i)):

    for (int i = 0; i < db.Itens.Count(); i++)
    {
        Item item = db.Itens.ElementAt(i);
        if (item.Id == 0) // put a condition
        {
            db.Itens.Remove(item);
            i--;
        }
    }

    OriginaleL’autore Fernando Mota

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *