c# – 无法从XNA中的列表中删除项目
我正在研究一个Flappy Bird克隆作为练习,因为我最近开始在XNA上编程,而且我遇到了这个我无法理解的错误.
我在Update()函数中包含了以下代码,其作用是在屏幕离开时删除管道,以免在创建更多内容时向左无限移动: //Pipe despawner foreach (var pipe in pipes) { if (pipe.position1.X <= -180) { pipes.Remove(pipe); } } 游戏运行正常,直到第一个管道离开屏幕,调试器暂停并通过以下消息发出这部分代码的信号: An unhandled exception of type 'System.InvalidOperationException' occurred in mscorlib.dll Additional information: Colección modificada; puede que no se ejecute la operación de enumeración. 对不起,第二部分是西班牙语,这是我系统的语言,但希望你知道如何解决问题. 考虑到游戏的简单性,我认为我可以简单地不包括这部分代码,结果是无限产生的管道对性能造成的影响很小,但我不想在我开始学习时立即采用这种做法.游戏编程. 解决方法
问题是您在枚举集合时修改集合(通过删除管道).这将始终在.NET中引发异常(如果您在多线程环境中执行此操作,则需要注意,因为您可以获得一些由于它而无法重现的异常).
解决它的一个简单方法是在枚举时保留“kill”列表: 列表killList = new List(); foreach (var pipe in pipes) { if (pipe.position1.X <= -180) { killList.Add(pipe) } } 更简单: IEnumerable<Pipe> killList = pipes.Where (p => p.position1.X < -100); 无论哪种方式,枚举这个新集合,并从主要元素中删除匹配元素(从而避免错误条件): foreach (Pipe p in killList) pipes.Remove(p); 你完成了!再次,请注意线程.如果要在另一个线程中创建新管道,则可能很容易与此管道“发生碰撞”并导致异常.如果是这种情况,请确保在这些代码段周围放置锁. 注意,如果使用LINQ方法,实际上可以内联“killList”: foreach (Pipe p in pipes.Where(p => p.Position1.X <= -100)) pipes.Remove(p); 正如@ rot13建议的那样,你也可以运行RemoveAll,从“Where”语句中传递谓词,如: pipes.RemoveAll(p => p.Position1.X <= -100); 这就像它得到的一样简单:) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |