C#使用foreach循环的注意点

foreach真正是靠迭代器实现的 https://blog.csdn.net/u013986317/article/details/85628565

1.不能在在循环体中删除或增加元素;

原因:在执行foreach循环时,集合内部有一个变量用于记录集合的版本,这个版本值会在元素个数发生改变的所有操作中发生修改,每次遍历时会检测这个变量有无发生变化,如果发生变化,则抛出异常。

2.不能在循环内部修改元素(无论值类型还是引用类型);

原因是,在遍历IEnumerator<T>的过程中,把当前的元素(即Current)暴露为只读属性。

3.可以在循环内部修改对象的属性。

解释:

以ArrayList为例,数组实现了IEnumerable接口。

必须实现IEnumerable接口的方法GetEnumerator();

GetEnumerator方法需要返回一个实现了IEnumerator接口的对象。所以ArrayListEnumeratorSimple必须实现IEnumerator接口

ArrayListEnumeratorSimple的构造方法:(注意这个version)

ArrayListEnumeratorSimple类分别实现了IEnumerator接口中的方法,IEnumerator接口有三个方法:

注意 Current只有get属性

ArrayListEnumeratorSimple类中对这三个方法的实现:

 在ArrayListEnumeratorSimple的构造方法中看到,迭代器在一开始就记录了元素的版本version,在所有会对集合元素数量有变化的地方,都会更新版本(version++),如Add,Clear等等:

而在执行MoveNext方法开始遍历集合时,一进来就对version进行了对比。如果发现版本发生变化,则抛出异常:集合已修改...

这就解释了第一个注意点。

关于第二点, “不能在循环内部修改元素(无论值类型还是引用类型);”,很明显,当前遍历到的元素Current 只有get属性,所以只能读,不能更改:

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值