如果您使用 LINQ 编写循环访问集合的代码,那么您是以声明性风格在编写代码。 这种风格更像是描述您想要实现的内容,而不是描述您所需要的实现方式。 如果您编写的代码要执行以下操作:1) 获取第一个元素;2) 测试该元素是否符合某种条件;3) 修改该元素;4) 将该元素放回列表中。那么,此代码就是命令性代码。 您是在告诉计算机您希望以何种方式完成任务。
在同一操作中混合这些代码风格正是导致问题的原因。 考虑以下情况:
假设您有一个链接列表,其中有三个项(a、b 和 c):
a -> b -> c
现在,假设您想在链接列表中移动,并添加三个新项(a'、b' 和 c')。 您希望生成如下所示的链接列表:
a -> a' -> b -> b' -> c -> c'
因此您编写代码来循环访问该列表,在每一项后面紧接着添加一个新项。 而实际发生的情况是,您的代码首先将看到 a 元素,然后在它后面插入 a'。 现在,您的代码将移动到列表中的下一节点,此时下一节点是 a'! 它会不假思索地向列表中添加一个新项 a''。
在实际中该如何解决这一问题? 您可以创建原始链接列表的副本,然后创建一个全新的列表。 或者,如果您正在编写纯粹的命令性代码,您可以找到第一项,添加新项,然后在链接列表中前进两步,跳过刚添加的元素。