说说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 ...
随机推荐
- httpclient htmlunit下载单个文件
httpclient public class Download { public static void main(String[] args) throws ClientProtocolExcep ...
- OVS处理upcall流程分析
处理upcall总体框架: 1.由函数handle_upcalls()批量处理(in batches)的是由内核传上来的dpif_upcalls,会解析出upcall的类型.这里主要看在内核中匹配流表 ...
- Redis中的管道(PipeLine)与事物(Transactions)
Redis中的管道(PipeLine)与事物(Transactions) 序言 Redis中的管道(PipeLine)特性:简述一下就是,Redis如何从客户端一次发送多个命令,服务端到客户端如何一次 ...
- 常用软件的安装(windows/linux)
1. matlab 2016b (两个 iso 文件)(windows) MATLAB R2016b 安装教程 2. clion 在 ubuntu 下的安装 ubuntu 14.04 Clion201 ...
- 自己动手编写一个VS插件(七)
作者:朱金灿 来源:http://blog.csdn.net/clever101 继续开发VS插件.今天在添加ATL控件时出现一个"未能返回新代码元素"的错误,如下图: 解决办法是 ...
- node lesson3
var express = require('express'); var superagent = require('superagent'); var cheerio = require('che ...
- 深度学习实战 Tricks
1. 梯度消失与梯度爆炸 gradient clipping 梯度爆炸:min(grad_max,grad) grad_max:梯度上限 梯度消失:max(grad_min, grad) grad_m ...
- win10系统应用打不开
可能有一些用户升级Win10之后遇到了应用商店.应用打不开或闪退的问题,此时可尝试通过下面的一些方法来解决. 1.点击任务栏的搜索(Cortana小娜)图标,输入Powershell,在搜索结果中右键 ...
- Codeforces 35E Parade 扫描线 + list
主题链接:点击打开链接 意甲冠军:特定n矩阵(总是接近底部x轴) 然后找到由上面的矩阵所包围的路径,的点 给定n 以下n行给定 y [x1, x2] 表示矩阵的高度和2个x轴坐标 思路: 扫描线维护每 ...
- 解决引用 System.Windows.Interactivity程序集生成多国语言文件夹fr、es、ja等问题
原文:解决引用 System.Windows.Interactivity程序集生成多国语言文件夹fr.es.ja等问题 通过以下方式对 System.Windows.Interactivity程序集添 ...