在for循环中删除对象

Tyl*_*r H 8 vb.net foreach loops object

我正在制作一个生存游戏并试图在它离开屏幕时移除它.这是代码:

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
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:mscorlib.dll中发生了'System.InvalidOperationException'类型的未处理异常附加信息:集合已被修改; 枚举操作可能无法执行.

如果有人能提供帮助那就太棒了,谢谢.

Tim*_*ter 15

在枚举期间,您无法从集合中删除对象.您根本无法修改集合.这将导致错误(Collection已被修改;枚举操作可能无法执行).但是您可以将要删除/删除的对象添加到另一个集合中:

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
Run Code Online (Sandbox Code Playgroud)

这些方法将导致列表更改其版本(在枚举期间检查):

  • 明确
  • 插入
  • InsertRange
  • 去掉
  • RemoveRange
  • RemoveAt移除
  • 相反
  • [Indexer setter]
  • 分类

另一个选择是使用a For-Loop并向后循环:

 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
Run Code Online (Sandbox Code Playgroud)

这不会引起该错误,但它不具有可读性.您需要从list.Count - 1To 转到,0因为您要删除会更改Count属性的项目以及在删除项目之前可用的索引导致现在ArgumentOutOfRangeException.

最后但并非最不重要的,您可以使用 List.RemoveAll:

lstEnemy.RemoveAll(Function(enemy) enemy.enemy.Left < 0)
Run Code Online (Sandbox Code Playgroud)


Adr*_*ian 1

.NET 确实不喜欢在枚举集合内容时更改集合。如果您打算像这样从集合中删除元素,您可以尝试将foreach循环更改为循环。for