【发布时间】:2016-05-28 09:34:27
【问题描述】:
为了简单起见;想象一个循环的类车;其中每辆车都包含一个汽车系统列表;第二个循环遍历每个系统,将它们从那辆汽车上移除。理想情况下,最后每辆车都没有系统。
这是简化的代码。
public class ParseCars: MonoBehaviour
{
foreach (cars a_car in cars_list)
{
// retrieve the systems for the current car
List<car_system> systems_list = a_car.ReturnSystemList();
foreach (car_system a_system in systems_list)
{
a_car.RemoveSystem(a_system);
}
Debug.Log("removed all systems for this car);
}
}
删除系统时,我所做的只是调用汽车类中包含的列表的 Remove 方法。
第一次移除成功;然后当需要删除下一个元素时,它不会再次执行 remove 调用,而是返回上一个 foreach,加载列表中的下一辆车。
查看下一个系统的名称;我仍然看到前一个,就像循环不会获取列表中的下一个项目一样。 我没有看到任何异常,这是我第一次看到这种行为,并且无法真正弄清楚发生了什么,因为我没有从调试器中得到任何反馈。
【问题讨论】:
-
显然这不是您算法的精确伪代码。正如@Saeid Yazdani 建议的那样,您可能会修改您的收藏(尽管您应该得到一个错误)或做其他错误。如果您切换到为您不会得到“CollecionModifiedException”,但如果不修改索引,代码将无法工作。我建议您使用 List.RemoveAll 方法清空列表或创建一个临时列表,其中包含要删除的元素并在原始列表上使用 RemoveRange
-
简化了;否则我应该添加至少 3 个以上的类和方法。 Saeid 发现了这个问题。
-
嘿@newbiez 怎么了。不要忘记在编程中作为一般主体,您在删除时经常需要遍历列表 BACKWARDS。赛义德在这里给了你答案。但不要忘记那个“技巧”,它是软件的基础。
-
嘿@JoeBlow;我懂了。我认为删除的方向无关紧要,因为 C# 列表不是像链表那样的顺序列表,也不是堆栈或堆。为何即使在这种情况下,这个老“伎俩”仍然存在?
-
@nbew - 我不知道 :O 我只是提醒一下,有时你必须使用那个“技巧”!