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的更多相关文章

  1. C# 使用IENUMERABLE,YIELD

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

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

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

  3. 【Unity3D/C#】利用IEnumerable<>和yield产生斐波那契数列

    using UnityEngine; using System.Collections; using System.Collections.Generic; public class YieldTes ...

  4. yield 用法分析

    yield 关键字向编译器指示它所在的方法是迭代器块.编译器生成一个类来实现迭代器块中表示的行为.在迭代器块中,yield 关键字与 return 关键字结合使用,向枚举器对象提供值.这是一个返回值, ...

  5. C#中yield return用法分析

    这篇文章主要介绍了C#中yield return用法,对比使用yield return与不使用yield return的流程,更直观的分析了yield return的用法,需要的朋友可以参考下. 本文 ...

  6. Enumerable和yield

    说说IEnumerable和yield IEnumerable数据类型是我比较喜欢的数据类型,特别是其强类型IEnumerable<T>更获得Linq的支持使得代码看起来更加优雅.整洁. ...

  7. C# yield return用法

    本文实例讲述了C#中yield return用法,并且对比了使用yield return与不使用yield return的情况,以便读者更好的进行理解.具体如下: yield关键字用于遍历循环中,yi ...

  8. C#中,什么时候用yield return

    yield关键字用于遍历循环中,yield return用于返回IEnumerable<T>,yield break用于终止循环遍历. 有这样的一个int类型的集合: static Lis ...

  9. C#中的yield

    一.C#中yield关键字用于遍历循环中,yield语句的两种形式 yield return用于返回IEnumerable<T>, yield break用于终止循环遍历. 二.yield ...

随机推荐

  1. Linux下安装mysql(1)(CentOS)

    标题是(1)也就是说这次是基础安装,这种方式安装,没有组的创建,权限管理,配置文件更改等,仅仅是最基本的安装,适合第一次在linux上安装mysql的新手 1.准备好安装包(Linux-Generic ...

  2. jQuery插件开发小总结

    另一篇 jQuery插件开发通常有3种方式 通过$.extend()来扩展jQuery 通过$.fn 向jQuery添加新的方法 通过$.widget()应用jQuery UI的部件工厂方式创建 通常 ...

  3. hudson搭建经验总结

    作者:朱金灿 来源:http://blog.csdn.net/clever101 hudson 是一种革命性的开放源码 CI (持续集成)服务器,随着工程源码越来越庞大,把源码编译工作放在本地机器已不 ...

  4. 转载来自朱小厮博客的 一文看懂Kafka消息格式的演变

    转载来自朱小厮博客的 一文看懂Kafka消息格式的演变     ✎摘要 对于一个成熟的消息中间件而言,消息格式不仅关系到功能维度的扩展,还牵涉到性能维度的优化.随着Kafka的迅猛发展,其消息格式也在 ...

  5. Delphi Bpl包学习

    对于BPL包,我个人理解是:就是一种封装方式,和DLL,EXE类似,把代码放到包(package)里面保存而已. 一.先说说如何创建BPL包 1.   打开delphi IDE(delphi7 为例) ...

  6. OpenGL中GLSL渲染茶壶光照完整程序

    顶点着色器VertexShader.txt: uniform vec3 lightposition;//光源位置 uniform vec3 eyeposition;//相机位置 uniform vec ...

  7. 编码(encode)问题

    1. UTF-8 与 GBK UTF-8: 允许含 BOM,但通常不含 BOM 用以解决国际上字符的一种多字节编码, 英文:8 bits(1 byte) 中文:24 bits(3 bytes) UTF ...

  8. wxWidgets编译和在VC 6.0中的配置

    1. 安装  运行wxMSW-2.8.3-Setup1.exe,将之安装到不带空格符号的目录中,本例为C:/wxWidgets-2.8.3:   2. 编译和配置 (1) 用VC6.0编译  进入C: ...

  9. Python+Django+SAE系列教程10-----Django模板

    在本章中,我们开始模板,在前面的章节,您可能已经注意到,我们回到文本的方式有点特别的示例视图. 那.HTML直接在硬编码 Python 其中代码. 这的确是一个小BT. def current_dat ...

  10. asp .net 大文件传输配置

    asp .net config配置 需要在配置文件里面设置文件上传限定的两个属性值:maxAllowedContentLength,maxRequestLength 允许上传文件的长度,和请求的长度, ...