不要通过enumerator来改变集合的内容

这话题已经被提过很多次,Java和.NET社区都应该很熟悉这点了,但总是会见到有人犯这个错误……

举个糟糕的代码为例:
using System;
using System.Collections.Generic;
using System.Linq;

namespace BadExample {
static class Program {
static void Main( string[ ] args ) {
var dummyList = new List<int> { 1, 2, 3, 4, 5 };

// try to remove all entries with ForEach (or foreach statement).
dummyList.ForEach( item => dummyList.Remove( item ) );

// dummyList should be empty now, but...

// we still see 2 and 4 in the list!
dummyList.ForEach( item => Console.WriteLine( item ) );
}
}
}

代码中的两个循环用LINQ的扩展方法或者用C#内建的foreach语句效果都一样。很容易看出,第11行改变了dummyList的内容。但比较隐蔽的是,这个改变是通过IEnumerable<T>.GetEnumerator()得到一个IEnumerator<T>之后来做的。因为是通过enumerator(C++和Java社区习惯称之为iterator)来做修改,我们无法保证一个集合被修改后,先前得到的enumerator对象还能正确遍历集合。上面的例子里会看到“把表里的每个元素都删除”后,表里还剩下2和4。由于集合内容发生了变化,它们正好被跳过去了。

过程:
{ 1, 2, 3, 4, 5 }
删除位置0的元素,剩下{ 2, 3, 4, 5 }
删除位置1的元素,剩下{ 2, 4, 5 }
删除位置2的元素,剩下{ 2, 4 }
位置3超过表的长度,返回

想强调的就是,用LINQ的时候千万不要试图改变原本集合里的内容!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值