
那一次的邂逅:
第一次见到yield的时候,内心中充满了各种声音,这是个啥子鬼扯扯的东西?C#有这个破玩意吗?这是一个关键字?按捺不住内心的疑惑,熟练的打开了宇宙第一IDE ------ VS2015.

卧槽,还真有这个关键字.. 看一下解释 "yield 关键字" ,可以,不和我多逼逼! 微软大佬不愧是微软大佬,就是这么高冷.
魂牵梦绕:
面对大佬如此爱答不理的态度,勾引起了我单纯内心的无限遐想,先从字面意思yield理解:产量,产出。难道这个是一个集合应当具有的属性? 找到我们的老朋友List<T>:

从yield的字面意思上入手,我们把关注点放在IEnumerable接口上,微软给出的解释是:公开的枚举数,该枚举数支持在非泛型集合上进行简单的迭代.
在C#要对一个集合进行遍历有两种方式:
1.For循环
2.Foreach循环
对于Foreach循环,我们要为这个集合定义一个迭代器才能使用微软大佬给我们提供的福利(Foreach).

眉目传情:
控制不住自己的情绪,事不宜迟,先建立一个Test<T>类来实现IEnumerable来试一试:
从代码中可以看出,要实现IEnumerable接口,必须要实现GetEnumerator()方法, 并且返回的类型是IEnumerator, 所以现在我们要先实现IEnumerator这个接口
实现了IEnumerator接口,必须要实现 Current属性,以及MoveNext() 和 Reset()方法。 并且使用了嵌套类TestEnumerator,为什么要使用嵌套类呢,客官莫急莫急,且听臣娓娓道来.
Current : 简单的说就是保存集合当前的值,并且只有get权限.
MoveNext():返回的是个bool类型的值,用来判断集合是否还有下一个元素。 如果集合还有元素则返回true,反之亦然。
Rest():对集合进行重置操作.
为什么要使用嵌套类呢? 因为我们要对Test<T>类的实例进行操作,如果我们使用了一个顶级类,那么会得不到相应的数据(没有权限查看).
添加实现得到的代码如下:
在下比较懒,对于Test<T>的内部values只用了数组来存,有时间 我会更新成用链表的数据结构来实现这个方法,但是这个不是今天的重点..
测试下代码:
初次相识:
![]()
说了半天,怎么看不到yield的影子,故弄玄虚,博主你是不是个睿智啊??? 不好意思,让各位大爷久等了,现在闪亮的请出我们今天的主角 ”yield“。
在C#1.0要需要手动实现迭代器,洋洋洒洒几十行的代码,微软大佬你就不能对小弟好一些,使用写短小干练的方式吗? 于是乎,大佬决定相应小弟们的号召,使用关键字”yield“ 对迭代器进行封装.. (微软大佬就是好,没事就给小弟们吃糖(语法糖),牙齿都给我吃的曲黑!!)
不多逼逼,简单粗暴点,直接上代码:
重新实现GetEnumerator()方法:
春宵一刻:
利用yield,可以简单的实现Linq中的where条件过滤(惰性过滤)。
在Test<T>中添加where方法:
测试:
贤者时间:
C#对许多设计模式进行了间接的实现,使得实现这些模式变得很容易。相对来针对某一特定的设计模式直接实现的的特性比较少。从foreach代码中看出,C#1对迭代器模式进行了直接的支持,但是没有对进行迭代的集合进行有效的支持。对集合实现一个正确的IEnumerable很耗时,容易出错也很枯燥。在C#2中,编译器为我们做了很多工作,为我们实现了一个状态机来实现迭代。链表 结构
代码中还有些瑕疵的地方,比如没有处理异常,没有使用泛型的接口等。还有yield break的时候,需要释放资源的问题,具体的细节,有时间在写把!
微软大佬,法力无边,使我螺旋升天。链表 结构--------- by 没有对象的野指针
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-79422-1.html
唉你哦