关于foreach的那些事

今天写关于foreach的一些东西包括一下内容

 

foreach的介绍

foreach的简单用法

手工实现 IEnumeratorIEnumerable接口来兼容foreach

yield return关键字和迭代器

 

foreach的介绍

类似与for语句遍历集合(数组等数据结构)的语句。

看一下masn的介绍”foreach 语句对实现 System.Collections. IEnumerableSystem.Collections.Generic. IEnumerable< T> 接口对象集合中的每个元素重复一组嵌入式语句”

另外在遍历过程中可以使用 break continue goto return throw这些方式在中途退出

很重要的一点是利用foreach只能实现只读,要修改集合中的内容就必须用for

更重要的是它的速度比用for语句快

关于效率问题可以参考《深入探讨C#foreach语句》的前半部分

文章地址:http://developer.51cto.com/art/200908/147347.htm

 

foreach的简单用法

直接上代码

比较值得注意是交错数组部分

因为交错数组是数组的数组

所以代码中a3类型是int[][] a的类型是int[] e的类型是int

 

手工实现 IEnumeratorIEnumerable接口来兼容foreach

 

讲这个之前先讲一下foreach的原理(一下来自《C#入门经典》)

(1)调用collectionObject.GetEnumerator(),返回一个IEnumerator引用。这个方法可以通过IEnumerable接口的实现代码来获得。但这是可选的。
(2)调用返回的IEnumerator接口的MoveNext()方法。
(3)如果MoveNext()方法返回true,就使用IEnumerator接口的Current属性获取对象的一个引用,用于foreach循环。
(4)重复前面两步,直到MoveNext()方法返回false为止,此时循环停止。

那么如果你要为自己建立的集合提供foreach语句的支持,按照MSDN的说法应该“在 C# 中,集合类并非必须严格从 IEnumerable 和 IEnumerator 继承才能与 foreach 兼容;只要类有所需的 GetEnumeratorMoveNextResetCurrent 成员,便可以与 foreach 一起使用。省略接口的好处为,使您可以将 Current 的返回类型定义得比 object 更明确,从而提供了类型安全。”

我们先来看一下这两个接口的定义

只要我们的集合类能实现这两个接口就可以使用foreach对集合进行遍历

具体的代码如下

如果还有不清楚可以对比一下MSDN中的实例

http://msdn.microsoft.com/zh-cn/library/9yb8xew9%28v=VS.80%29.aspx

 

yield return关键字和迭代器

如果为了让集合支持foreach语句要多出那么一大块的代码,确是有点麻烦。

所以自然有一种简单的办法出现了,使用迭代器。

这东西可以再后台帮你生成很多代码

在为类或结构创建迭代器时,不必实现整个 IEnumerator 接口。

当编译器检测到迭代器时,它将自动生成 IEnumerator 接口的 CurrentMoveNextDispose 方法。

然后利用yield return语句依次返回每个元素,选择要在foreach循环中使用的值。

到达yield return语句时,会保存当前迭代的位置,下次调用迭代器时将从此位置开始执行。

那如何创建一个迭代器块呢?

也很简单yield 关键字就是向编译器指示它所在的方法是迭代器块。

不知道这样写有没有表达清楚,还是代码来的直接点

实现了一个打印素数的功能。

值得一提的是,那些数是一个一个出来的。可以再输出语句后再加输出点东西就看出来了

也就是迭代器一次只返回一个结果,调用yield的时候会中断代码的执行,等foreach开始新的循环代码才回复执行。

 

同时也给一段比较短的代码作为对照

如果有心的话应该可以猜到 yield return 返回的是一个object类型的值。所以不用再自己指定了。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值