说说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表达式将得到更优雅的表达:

寥寥两行代码,语义十分清晰,根本无须注释.

 
 
 
标签: lamda

Enumerable和yield的更多相关文章

  1. 集合 Enumerable Enumerator yield

    集合: 通过索引来访问成员,--引申到索引器 的使用 for foreach循环遍历 --引申到 IEnumerable IEnumerator(会引申到yield) 常用的集合操作,add, ins ...

  2. C# 使用IEnumerable,yield 返回结果,同时使用foreach时,在循环内修改变量的值无效(二)

    前言 在上篇文章中我得出结论,遍历迭代器修改迭代器中项目的值未生效,是因为使用了yield return,并且每次遍历迭代器都执行返回迭代器的方法.这篇文章是接着上篇文章,从代码实现的角度来验证出现这 ...

  3. C#中的using和yield return混合使用

    最近写代码为了为了省事儿用了几个yield return,因为我不想New一个List<T>或者T[]对象再往里放元素,就直接返回IEnumerable<T>了.我的代码里还有 ...

  4. C#高级功能(二)LINQ 和Enumerable类

    介绍LINQ之前先介绍一下枚举器 Iterator:枚举器如果你正在创建一个表现和行为都类似于集合的类,允许类的用户使用foreach语句对集合中的成员进行枚举将会是很方便的.我们将以创建一个简单化的 ...

  5. C# 基础小知识之yield 关键字 语法糖

    原文地址:http://www.cnblogs.com/santian/p/4389675.html 对于yield关键字我们首先看一下msdn的解释: 如果你在语句中使用 yield 关键字,则意味 ...

  6. C# 使用IENUMERABLE,YIELD

    C# 使用IENUMERABLE,YIELD 前言 在上篇文章中我得出结论,遍历迭代器修改迭代器中项目的值未生效,是因为使用了yield return,并且每次遍历迭代器都执行返回迭代器的方法.这篇文 ...

  7. using和yield return

    C#中的using和yield return混合使用 最近写代码为了为了省事儿用了几个yield return,因为我不想New一个List<T>或者T[]对象再往里放元素,就直接返回IE ...

  8. HeadFirst Ruby 第十章总结 Comparable & Enumerable

    导言 这一章的标题是 Ready-Made Mixes, 也就是 Ruby 已经准备好的用于 Mix-in 的 Modules, 它们是: Comparable 和 Enumerable, Compa ...

  9. python yield yield from

    1.可迭代对象 具备可迭代的能力,即enumerable,在python中指的是可以通过for-in去逐个访问元素的一些对象,比如元组tuple,列表list,字符串string,文件对象file等. ...

随机推荐

  1. RTP 记录 log 该机制

    我们 RCV 在这里,经常跑concurrent request RTP: Receiving Transaction Processor, 它主要是用来处理 RCV_TRANSACTIONS_INT ...

  2. 项目中经常使用的JS方法汇总,非常有用

    // 对Date的扩展,将 Date 转化为指定格式的String   // 月(M).日(d).小时(h).分(m).秒(s).季度(q) 可以用 1-2 个占位符,   // 年(y)可以用 1- ...

  3. linux_无密登录

    使用下例中ssky-keygen和ssh-copy-id,仅需通过3个步骤的简单设置而无需输入密码就能登录远程Linux主机. ssh-keygen 创建公钥和密钥. ssh-copy-id 把本地主 ...

  4. word 一些有用的技巧

    为了能够word入代码,而且具备代码高亮显示功能.这里我提供一个工具------Notepad++,它具备一般文本的功能,且具备编写代码的功能. 包含代码排版,高亮显示,加入和删除凝视等.  在  语 ...

  5. 详解JMeter函数和变量

    JMeter函数可以被认为是某种特殊的变量,它们可以被采样器或者其他测试元件所引用.函数调用的语法如下: ${__functionName(var1,var2,var3)} 其中,__function ...

  6. 【高德地图API】从零开始学高德JS API(五)路线规划——驾车|公交|步行

    原文:[高德地图API]从零开始学高德JS API(五)路线规划——驾车|公交|步行 先来看两个问题:路线规划与导航有什么区别?步行导航与驾车导航有什么区别? 回答: 1.路线规划,指的是为用户提供3 ...

  7. Oracle 11g 环境,使用utl_smtp创建一个存储过程来发送邮件

    太多的在线电子邮件存储过程.我不转发,弄个作为一个简单的例子演示. create or replace procedure Send_mail(mail_body varchar2) is smtp_ ...

  8. Team City的安装1

    持续集成工具 Team City的安装 前两个月很大一部分精力投入在做部门的持续集成,从概念的了解和工具的选型,再到安装,部署,操作,到最后的真实项目持续集成应用的上线,写了一份手册,包括安装,配置, ...

  9. NGUI使用教程(2) 使用NGUI创建2D场景而且加入标签和button

    1.创建2D场景 要使用NGUI创建2D场景,首先咱们必须新建一个项目,而且导入NGUI作为这个项目的插件,相信假设看过上一篇教程都知道怎么导入NGUI了,这里就不赘述,假设有疑问的能够去看上一篇教程 ...

  10. YII编码规范

    类名称: 驼峰式 首字母大字 class PointController class PointRatioController 公共成员方法: 驼峰式 首字母小写 public function ge ...