2013-05-24 12 views
6

Ich mache ein Überleben Spiel und versuche, ein Objekt zu entfernen, wenn es vom Bildschirm verschwindet. Hier ist der Code:Entfernen Sie ein Objekt, wenn in einer für jede Schleife

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 

Der Fehler ich erhalte, ist: Eine nicht behandelte Ausnahme des Typs ‚System.InvalidOperationException‘ ist in mscorlib.dll aufgetreten Zusätzliche Informationen: Die Auflistung wurde geändert; Aufzählungsoperation wird möglicherweise nicht ausgeführt.

Wenn jemand helfen könnte, wäre das großartig, danke.

+2

Sie canot die Sammlung wie diese während Schleifen ändern aus offensichtlichen Gründen, wenn Sie darüber nachdenken. Holen Sie sich einen Verweis auf das Objekt, während in der Schleife, dann löschen – DavidB

Antwort

1

.NET mag es wirklich nicht, wenn Sie eine Sammlung ändern, wenn Sie gerade dabei sind, ihren Inhalt zu nummerieren. Sie könnten versuchen, Ihre foreach Schleife auf eine for Schleife zu ändern, wenn Sie Elemente aus der Sammlung wie folgt zu entfernen planen.

13

Sie können ein Objekt während der Enumeration nicht aus einer Sammlung löschen. Sie können die Sammlung überhaupt nicht ändern. Dies führt zu einem Fehler (Sammlung wurde geändert; Aufzählungsoperation möglicherweise nicht ausgeführt). Aber Sie könnten die Objekte hinzufügen, die Sie löschen möchten/entfernen, um eine andere Sammlung:

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 

Diese Methoden werden eine Liste führen, es zu ändern ist Version (die während der Enumeration aktiviert ist):

  • hinzufügen
  • Klar
  • Insert
  • Insert
  • entfernen
  • RemoveRange
  • RemoveAt
  • umge
  • [der Indexer Setter]
  • Sortieren

Eine weitere Option ist ein For-Loop und Schleife nach hinten zu verwenden:

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 

Dieser Wille nicht diesen Fehler zu erhöhen, aber es ist nicht so lesbar. Sie müssen von list.Count - 1 zu 0 gehen, da Sie Elemente entfernen möchten, die die Count-Eigenschaft ändern würden, und ein Index, der verfügbar war, bevor das Element entfernt wurde, verursacht jetzt eine ArgumentOutOfRangeException.

Last but not least, können Sie verwenden List.RemoveAll:

lstEnemy.RemoveAll(Function(enemy) enemy.enemy.Left < 0) 
+1

+1 Große Antwort –

+0

andere Option ist eine Weile zu verwenden. gute Antwort –

0

Ein Beispiel unter Verwendung von 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--; 
    } 
} 
Verwandte Themen