登录
/
注册
首页
论坛
其它
首页
科技
业界
安全
程序
广播
Follow
关于
签到
每天签到奖励2-10圆
导读
排行榜
TG频道
发帖说明
登录
/
注册
账号
自动登录
找回密码
密码
登录
立即注册
搜索
搜索
关闭
CSDN热搜
程序园
精品问答
技术交流
资源下载
本版
帖子
用户
软件
问答
教程
代码
写记录
VIP申请
VIP网盘
网盘
联系我们
发帖说明
每日签到
道具
勋章
任务
淘帖
动态
分享
留言板
导读
设置
我的收藏
退出
腾讯QQ
微信登录
返回列表
首页
›
业界区
›
业界
›
先说IEnumerable,我们每天用的foreach你真的懂它吗? ...
先说IEnumerable,我们每天用的foreach你真的懂它吗?
[ 复制链接 ]
站竣凰
2025-5-29 00:11:43
我们先思考几个问题:
为什么在foreach中不能修改item的值?
要实现foreach需要满足什么条件?
为什么Linq to Object中要返回IEnumerable?
接下来,先开始我们的正文。
自己实现迭代器
.net中迭代器是通过IEnumerable和IEnumerator接口来实现的,今天我们也来依葫芦画瓢。
首先来看看这两个接口的定义:
并没有想象的那么复杂。其中IEnumerable只有一个返回IEnumerator的GetEnumerator方法。而IEnumerator中有两个方法加一个属性。
接下来开发画瓢,我们继承IEnumerable接口并实现:
下面使用原始的方式调用:
有朋友开始说了,我们平时都是通过foreache来取值的,没有这样使用过啊。好吧,我们来使用foreach循环:
为什么说基本上是等效的呢?我们先看打印结果,在看反编译代码。
由此可见,两者有这么个关系:
我们可以回答第一个问题了“为什么在foreach中不能修改item的值?”:
我们还记得IEnumerator的定义吗
接口的定义就只有get没有set。所以我们在foreach中不能修改item的值。
我们再来回答第二个问题:“要实现foreach需要满足什么条件?”:
必须实现IEnumerable接口?
NO
我们自己写的MyIEnumerable删掉后面的IEnumerable接口一样可以foreach(不信?自己去测试)。
所以要可以foreach只需要对象定义了GetEnumerator无参方法,并且返回值是IEnumerator或其对应的泛型。细看下图:
也就是说,只要可以满足这三步调用即可。不一定要继承于IEnumerable。有意思吧!
下次面试官问你的时候一定要争个死去活来啊,哈哈!
yield的使用
你肯定发现了我们自己去实现IEnumerator接口还是有些许麻烦,并且上面的代码肯定是不够健壮。对的,.net给我们提供了更好的方式。
你会发现我们连MyIEnumerator都没要了,也可以正常运行。太神奇了。yield到底为我们做了什么呢?
好家伙,我们之前写的那一大坨。你一个yield关键字就搞定了。最妙的是这块代码:
这就是所谓的状态机吧!
我们继续来看GetEnumerator的定义和调用:
我们调用GetEnumerator的时候,看似里面for循环了一次,其实这个时候没有做任何操作。只有调用MoveNext的时候才会对应调用for循环:
现在我想可以回答你“为什么Linq to Object中要返回IEnumerable?”:
因为IEnumerable是
延迟加载
的,每次访问的时候才取值。也就是我们
在Lambda里面写的where、select并没有循环遍历(只是在组装条件)
,只有在ToList或foreache的时候才真正去集合取值了。这样大大提高了性能。
如:
这个时候得到了就是IEnumerable对象,但是没有去任何遍历的操作。(对照上面的gif动图看)
什么,你还是不信?那我们再来做个实验,自己实现MyWhere:
现在看到了吧。执行到MyWhere的时候什么动作都没有(
返回的就是IEnumerable
),只有执行到ToList的时候才代码才真正的去遍历筛选。
这里的MyWhere其实可以用扩展方法来实现,提升逼格。(Linq的那些查询操作符就是以扩展的形式实现的)[了解扩展方法]。
怎样高性能的
随机
取IEnumerable中的值
这段代码来源《深入理解C#》,个人觉得非常妙。贴出来给大家欣赏哈。
结束:
demo下载:http://pan.baidu.com/s/1dE94c1b
接下篇:《再讲IQueryable,揭开表达式树的神秘面纱》
本文以同步至《C#基础知识巩固系列》
来源:新程序网络收集,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
先说
IEnumerable
我们
每天
用的
相关帖子
为什么我们需要云身份?统一身份认证的现实与突围
读心与芯:我们与机器人的无限未来05未来之路
Facebook内部都在用的存储引擎,LSM凭什么能硬扛亿级写入流量?
CMake构建学习笔记21-通用的CMake构建脚本
外国黑阔用的webshell木马
2025年推荐6个好用的 Postman 替代工具
阿德勒的课题分离是很好用的东西
一天一款实用的AI工具,第4期,AI翻译成英语
【IoTDB 线上小课 14】我们为什么要做树表双模型?
Kubernetes存储卷:保障有状态应用的数据持久化
vip免费申请,1年只需15美金$
回复
使用道具
举报
提升卡
置顶卡
沉默卡
喧嚣卡
变色卡
千斤顶
照妖镜
相关推荐
业界
为什么我们需要云身份?统一身份认证的现实与突围
0
764
讥慰捷
2025-09-26
安全
读心与芯:我们与机器人的无限未来05未来之路
0
3
恶凝毛
2025-09-26
业界
Facebook内部都在用的存储引擎,LSM凭什么能硬扛亿级写入流量?
0
387
乳杂丫
2025-09-28
业界
CMake构建学习笔记21-通用的CMake构建脚本
0
181
坟菊
2025-09-28
程序
外国黑阔用的webshell木马
0
28
新程序
2025-10-01
业界
2025年推荐6个好用的 Postman 替代工具
0
319
欧阳雪枫
2025-10-05
业界
阿德勒的课题分离是很好用的东西
0
101
锦惺
2025-10-05
安全
一天一款实用的AI工具,第4期,AI翻译成英语
1
144
章绮云
2025-10-06
安全
【IoTDB 线上小课 14】我们为什么要做树表双模型?
0
965
赘暨逢
2025-10-07
业界
Kubernetes存储卷:保障有状态应用的数据持久化
0
87
计海龄
2025-10-10
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
回复
本版积分规则
回帖并转播
回帖后跳转到最后一页
签约作者
程序园优秀签约作者
发帖
站竣凰
2025-5-29 00:11:43
关注
0
粉丝关注
28
主题发布
板块介绍填写区域,请于后台编辑
财富榜{圆}
anyue1937
9999501
dage888
999994
富账慕
10013
4
匝抽
9986
5
孙淼淼
9992
6
筒濂
9985
7
柴古香
9993
8
凌彦慧
9991
9
崔瑜然
9984
10
慢秤
9979
查看更多