当前位置: 首页 > 编程语言 > C#

走过一个foreach什么时候可以修改?分享

时间:2023-04-10 19:25:03 C#

经历一个foreach什么时候可以修改?我想在获取foreach循环的成员的同时执行foreach循环,但这会引发错误。我唯一的想法是在这个循环中创建另一个列表来找到要删除的切片,然后循环遍历新列表以从Pizza中删除该项目。foreach(varSliceinPizza){if(Slice.Flavor=="香肠"){Me.Eat(Slice);//这会从列表中删除一个项目:"Pizza"}}你可以通过我迄今为止发现的最简单的方式来做到这一点(我认为它是我发明的,当然它不是真的;))foreach(varSliceinPizza.ToArray()){if(Slice.Flavor=="Sausage")//每个都有自己的..会去烧烤{Me.Eat(Slice);}}因为它迭代循环的固定副本。它会遍历所有项目,即使它们已被删除。得心应手不是!(顺便说一句,这是一种迭代集合副本的便捷方法,它是线程安全的,并且在对象被锁定时删除:锁定,获取ToArray()副本,释放锁,然后迭代)希望有帮助!如果您必须遍历列表并需要删除项目,请使用for循环向后迭代://取自PreetSangha的答案并修改for(inti=Pizza.Count-1;i>=0,i--){varSlice=披萨[i];if(Slice.Flavor=="香肠"){Me.Eat(Slice);//这会从列表中删除一个项目:"Pizza"}}向后迭代的原因是当您删除Elements时,您不会遇到因访问Pizza[5]而导致的IndexOutOfRangeException,我们删除了第六个元素。使用for循环的原因是因为迭代器变量i与Pizza无关,因此您可以修改Pizza而无需枚举器“中断”使用for循环而不是foreachfor(inti=0;i是最明确的方法做到这一点的方法是构建一个吃切片然后处理它的列表,避免在循环中改变原始枚举。我从来不喜欢使用索引循环,因为它容易出错。ListslicesToEat=newList();foreach(varSliceinPizza){if(Slice.Flavor=="Sausage"){slicesToEat.Add(Slice);}}foreach(varsliceinslicesToEat){Me.Eat(slice);}也许改变您的Me.Eat()签名以获得IEnumerableMe.Eat(Pizza.Where(s=>s.Flavor=="Sausage").ToList());这允许您在一行代码中执行任务。然后你的Eat()就像:publicvoidEat(IEnumerableremove){foreach(Slicerinremove){Pizza.Remove(r);}}VB6风格的“Collection”对象允许在枚举期间修改,并且似乎能够合理地工作。太糟糕了,它还有其他限制(键类型仅限于不区分大小写的字符串)并且不支持泛型,因为其他集合类型都不允许修改。坦率地说,我不清楚为什么微软的iEnumerable契约需要在修改集合时抛出异常。我理解一个要求,如果对集合的更改使枚举无法继续而没有怪癖(跳过或复制在枚举期间未更改的值,崩溃等),则抛出异常但没有理由不做所以允许一个合理的可枚举集。您在哪里可以订购切片有单独浇头的披萨?无论如何...使用Linq://“Me.Eat()”应该是“this.Eat()”吗?披萨前两行创建了一个仅包含香肠片的新列表。第三个将获取新的子集并将每个切片传递给Me.Eat()。{和;}可能是多余的。这不是最有效的方法,因为它首先制作一个副本(就像已经给出的许多其他方法一样),但它肯定是干净和可读的。顺便说一句,这只是为了后代,因为已经给出了最好的答案——按索引向后迭代。pizza是什么系列?如果是List,那么可以调用RemoveAll方法:以上是C#学习教程:走过一个foreach什么时候可以修改?如果分享的内容对你有用,需要进一步了解C#学习教程,希望你多多关注---Pizza.RemoveAll(slice=>string.Equals(slice.Flavor,"Sausage"));本文整理自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: