说说IEnumerable和yield
IEnumerable数据类型是我比较喜欢的数据类型,特别是其强类型IEnumerable<T>更获得Linq的支持使得代码看起来更加优雅、整洁。
编写返回值为IEnumerable(或IEnumerabl<T>,下同)的方法时,会经常用到yield。近几天在开发时碰到一个很头疼的问题,终于在昨天解决。现将问题即解决过程记录如下:
一、问题的出现:
编写返回值为IEnumerable的方法时,可以用两种方式返回值:
1、构造一个实现IEnumerable接口的对象,并返回。
2、在方法体内使用yield return逐个返回可能的值,如果中途遇到不需要再返回值的情形,可以使用yield break;语句.
有一天突发奇想,能不能混合这两种方式:如果业务逻辑不允许返回值,则用yield break,否则构建一个实现IEnumerable接口的对象返回呢?
于是按如下思路编写代码:

写完后发现return语句总是报错:无法从迭代器返回值。请使用yield return语句返回值,或使用yield break语句结束迭代。
二、问题的解决:
仔细思考后,发现迭代器的原理大致如下:
如果方法按迭代方法执行,则完全以yield return语句来进行迭代。否则,返回一个IEnumerable对象,运行时会迭代该对象。
最终两种方法重写代码均获得通过。
方式一:纯迭代器方式

方式二:纯构造IEnumerable对象

三、思考
1、从代码的可读性和优雅性两个方面考虑,在允许的情况下应尽可能构造IEnumerable对象作为返回值,确有必要才用yield return语句。
2、语句内出现foreach时,请尽量借用强大的lamda表达式,而不是构造返回IEnumerable的方法或是使用foreach循环。
3、请尽量使用IEnumerable<T>而不是IEnumerable,以便获得强大的linq支持。
下面的方法将根据方法名和参数列表从一个方法列表中找到最合适的方法:

而采用lamda表达式将得到更优雅的表达:

寥寥两行代码,语义十分清晰,根本无须注释.
说说IEnumerable和yield的更多相关文章
- C# 使用IENUMERABLE,YIELD
C# 使用IENUMERABLE,YIELD 前言 在上篇文章中我得出结论,遍历迭代器修改迭代器中项目的值未生效,是因为使用了yield return,并且每次遍历迭代器都执行返回迭代器的方法.这篇文 ...
- C# 使用IEnumerable,yield 返回结果,同时使用foreach时,在循环内修改变量的值无效(二)
前言 在上篇文章中我得出结论,遍历迭代器修改迭代器中项目的值未生效,是因为使用了yield return,并且每次遍历迭代器都执行返回迭代器的方法.这篇文章是接着上篇文章,从代码实现的角度来验证出现这 ...
- 【Unity3D/C#】利用IEnumerable<>和yield产生斐波那契数列
using UnityEngine; using System.Collections; using System.Collections.Generic; public class YieldTes ...
- yield 用法分析
yield 关键字向编译器指示它所在的方法是迭代器块.编译器生成一个类来实现迭代器块中表示的行为.在迭代器块中,yield 关键字与 return 关键字结合使用,向枚举器对象提供值.这是一个返回值, ...
- C#中yield return用法分析
这篇文章主要介绍了C#中yield return用法,对比使用yield return与不使用yield return的流程,更直观的分析了yield return的用法,需要的朋友可以参考下. 本文 ...
- Enumerable和yield
说说IEnumerable和yield IEnumerable数据类型是我比较喜欢的数据类型,特别是其强类型IEnumerable<T>更获得Linq的支持使得代码看起来更加优雅.整洁. ...
- C# yield return用法
本文实例讲述了C#中yield return用法,并且对比了使用yield return与不使用yield return的情况,以便读者更好的进行理解.具体如下: yield关键字用于遍历循环中,yi ...
- C#中,什么时候用yield return
yield关键字用于遍历循环中,yield return用于返回IEnumerable<T>,yield break用于终止循环遍历. 有这样的一个int类型的集合: static Lis ...
- C#中的yield
一.C#中yield关键字用于遍历循环中,yield语句的两种形式 yield return用于返回IEnumerable<T>, yield break用于终止循环遍历. 二.yield ...
随机推荐
- iOS 多线程的使用
iOS 多线程 先看一篇阮一峰写关于进程和线程的文章,快速了解线程的相关概念. 随着现在计算机硬件的发展,多核心.高频率的cpu越来越普及,为了充分发挥cpu的性能,在不通的环境下实现cpu的利用最大 ...
- Android应用《撕开美女衣服》的实现过程及源代码
现在很多Android市场中都能找到关于美女的应用,比如 撕开美女衣服.吹裙子等. 这些应用的下载量挺大的,作为Android的开发人员或者一名技术人员我们不能只局限在欣赏应用的层面,很多时候需要我们 ...
- 集装箱set相关算法
set_union 算法set_union可构造S1.S2的并集.此集合内含S1或S2内的每个元素. S1.S2及其并集都是以排序区间表示.返回值是一个迭代器.指向输出区间的尾端. 因为S1和S ...
- 深度剖析:最新云端开发工具如何实现敏捷+DevOps开发落地
相信很多软件开发人员们对今年国内新兴的云端开发工具——华为软件开发云都有耳闻,有些人可能还免费体验过,由于它5人以下的团队是免费使用的,很庆幸本人的这个项目正好5个人,就注册使用了.下面就自己的使用心 ...
- React为啥很多类里的标签上事件处理函数要用bind(this)
render() { return ( <div> <p onClick={this.clickHandler.bind(this)}>vz</p> </di ...
- APP压力測试新手教程
Daniel Knott 用过各种不同编程语言和软件质量保证工具.他在软件开发和測试方面干了七年,自2010年,他一直在德国汉堡的XING AG公司就职,几个项目里,比方XING调查和XING建议,他 ...
- HTML5 的成长之路
html5历史 w3c从2008年提出html5的概念,目前html5的版本已经趋于稳定,也逐步得到了业界的认可和接受. 以前我们有一个疑问,HTML5与Flash究竟谁将在移动互联网时代称霸市场?这 ...
- hdu1845 Jimmy’s Assignment --- 完整匹配
意甲冠军: 它需要一个特殊的图,以找到最大匹配.该图的特征是:无向图,度的每个节点3.这是一个双边连接组件(the graph is 2-edge-connected (that is, at lea ...
- UVALive 6531 Go up the ultras 单调栈+RMQ
题目链接:点击打开链接 题意: 给定n座山 以下n个数字表示n座山的高度 若这座山u合法,则要满足: 1.若u的左边存在比u高的山,设v是u左边距离u近期的且严格比u高的山,在[v,u]之间至少有一座 ...
- Information Centric Networking Based Service Centric Networking
A method implemented by a network device residing in a service domain, wherein the network device co ...